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

(-)a/api.java/apichanges.xml (-1 / +18 lines)
Lines 73-79 Link Here
73
<!-- ACTUAL CHANGES BEGIN HERE: -->
73
<!-- ACTUAL CHANGES BEGIN HERE: -->
74
74
75
<changes>
75
<changes>
76
76
        <change id="queries">
77
            <api name="queries"/>
78
            <summary>Support for passing hint to the java infrastructure whether it should prefer source or binary</summary>
79
            <version major="1" minor="15"/>
80
            <date day="10" month="3" year="2008"/>
81
            <author login="tzezula"/>
82
            <compatibility addition="yes" modification="yes" semantic="compatible" source="compatible" binary="compatible"/>
83
            <description>
84
                <p>
85
                    It is possible for the SouceForBinaryQuery provider to specify whether the java module should prefer
86
                    sources or binaries. In general sources should be preferred for projects where user can make modification.
87
                    The binaries should be preferred for libraries and platforms where sources may not be complete or correct.
88
                </p>
89
            </description>
90
            <class package="org.netbeans.api.java.queries" name="SourceForBinaryQuery"/>
91
            <class package="org.netbeans.spi.java.queries" name="SourceForBinaryQueryImplementation2"/>
92
            <issue number="128695"/>
93
        </change>
77
        <change id="includes-excludes.classpath">
94
        <change id="includes-excludes.classpath">
78
            <api name="classpath"/>
95
            <api name="classpath"/>
79
            <summary>Support for specifying classpath inclusion</summary>
96
            <summary>Support for specifying classpath inclusion</summary>
(-)a/api.java/arch.xml (+81 lines)
Lines 958-961 Link Here
958
 </answer>
958
 </answer>
959
959
960
960
961
962
963
964
<!--
965
        <question id="arch-where" when="impl">
966
            Where one can find sources for your module?
967
            <hint>
968
                Please provide link to the Hg web client at
969
                http://hg.netbeans.org/
970
                or just use tag defaultanswer generate='here'
971
            </hint>
972
        </question>
973
-->
974
 <answer id="arch-where">
975
  <defaultanswer generate='here' />
976
 </answer>
977
978
979
980
<!--
981
        <question id="compat-deprecation" when="init">
982
            How the introduction of your project influences functionality
983
            provided by previous version of the product?
984
            <hint>
985
            If you are planning to deprecate/remove/change any existing APIs,
986
            list them here accompanied with the reason explaining why you
987
            are doing so.
988
            </hint>
989
        </question>
990
-->
991
 <answer id="compat-deprecation">
992
  <p>
993
   XXX no answer for compat-deprecation
994
  </p>
995
 </answer>
996
997
998
999
<!--
1000
        <question id="exec-ant-tasks" when="impl">
1001
            Do you define or register any ant tasks that other can use?
1002
            
1003
            <hint>
1004
            If you provide an ant task that users can use, you need to be very
1005
            careful about its syntax and behaviour, as it most likely forms an
1006
	          API for end users and as there is a lot of end users, their reaction
1007
            when such API gets broken can be pretty strong.
1008
            </hint>
1009
        </question>
1010
-->
1011
 <answer id="exec-ant-tasks">
1012
  <p>
1013
   XXX no answer for exec-ant-tasks
1014
  </p>
1015
 </answer>
1016
1017
1018
1019
<!--
1020
        <question id="resources-preferences" when="final">
1021
            Does your module uses preferences via Preferences API? Does your module use NbPreferences or
1022
            or regular JDK Preferences ? Does it read, write or both ? 
1023
            Does it share preferences with other modules ? If so, then why ?
1024
            <hint>
1025
                You may use
1026
                    &lt;api type="export" group="preferences"
1027
                    name="preference node name" category="private"&gt;
1028
                    description of individual keys, where it is used, what it
1029
                    influences, whether the module reads/write it, etc.
1030
                    &lt;/api&gt;
1031
                Due to XML ID restrictions, rather than /org/netbeans/modules/foo give the "name" as org.netbeans.modules.foo.
1032
                Note that if you use NbPreferences this name will then be the same as the code name base of the module.
1033
            </hint>
1034
        </question>
1035
-->
1036
 <answer id="resources-preferences">
1037
  <p>
1038
   XXX no answer for resources-preferences
1039
  </p>
1040
 </answer>
1041
961
</api-answers>
1042
</api-answers>
(-)a/api.java/manifest.mf (-1 / +1 lines)
Lines 1-6 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.api.java/1
2
OpenIDE-Module: org.netbeans.api.java/1
3
OpenIDE-Module-Specification-Version: 1.14
3
OpenIDE-Module-Specification-Version: 1.15
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/api/java/classpath/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/api/java/classpath/Bundle.properties
5
AutoUpdate-Show-In-Client: false
5
AutoUpdate-Show-In-Client: false
6
6
(-)a/api.java/src/org/netbeans/api/java/queries/SourceForBinaryQuery.java (-7 / +134 lines)
Lines 43-55 Link Here
43
43
44
import java.net.URL;
44
import java.net.URL;
45
import java.util.Arrays;
45
import java.util.Arrays;
46
import java.util.concurrent.CopyOnWriteArrayList;
46
import java.util.logging.Level;
47
import java.util.logging.Level;
47
import java.util.logging.Logger;
48
import java.util.logging.Logger;
49
import javax.swing.event.ChangeEvent;
48
import javax.swing.event.ChangeListener;
50
import javax.swing.event.ChangeListener;
49
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
51
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
52
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2;
50
import org.openide.filesystems.FileObject;
53
import org.openide.filesystems.FileObject;
51
import org.openide.filesystems.FileUtil;
54
import org.openide.filesystems.FileUtil;
55
import org.openide.util.ChangeSupport;
52
import org.openide.util.Lookup;
56
import org.openide.util.Lookup;
57
import org.openide.util.Parameters;
58
import org.openide.util.WeakListeners;
53
59
54
/**
60
/**
55
 * The query is used for finding sources for binaries.
61
 * The query is used for finding sources for binaries.
Lines 78-90 Link Here
78
     * @return a result object encapsulating the answer (never null)
84
     * @return a result object encapsulating the answer (never null)
79
     */
85
     */
80
    public static Result findSourceRoots (URL binaryRoot) {
86
    public static Result findSourceRoots (URL binaryRoot) {
81
        if (FileUtil.isArchiveFile(binaryRoot)) {
87
        checkPreconditions (binaryRoot);
82
            throw new IllegalArgumentException("File URL pointing to " + // NOI18N
83
                "JAR is not valid classpath entry. Use jar: URL. Was: "+binaryRoot); // NOI18N
84
        }
85
        if (!binaryRoot.toExternalForm().endsWith("/")) {
86
            throw new IllegalArgumentException ("Folder URL must end with '/'. Was: "+binaryRoot);
87
        }
88
        for (SourceForBinaryQueryImplementation impl : implementations.allInstances()) {
88
        for (SourceForBinaryQueryImplementation impl : implementations.allInstances()) {
89
            Result result = impl.findSourceRoots(binaryRoot);
89
            Result result = impl.findSourceRoots(binaryRoot);
90
            if (result != null) {
90
            if (result != null) {
Lines 96-101 Link Here
96
        }
96
        }
97
        LOG.log(Level.FINE, "findSourceRoots({0}) -> nil", binaryRoot);
97
        LOG.log(Level.FINE, "findSourceRoots({0}) -> nil", binaryRoot);
98
        return EMPTY_RESULT;
98
        return EMPTY_RESULT;
99
    }
100
    
101
    /**
102
     * Returns the source root for given binary root (for example, src folder for jar file or build folder).
103
     * In addition to the original {@link SourceForBinaryQuery#findSourceRoots(java.net.URL)} it provides 
104
     * information if the source root(s) should be preferred over the binaries used by the java infrastructure.
105
     * Most of the clients don't need this information, so thay can use the original
106
     * {@link SourceForBinaryQuery#findSourceRoots(java.net.URL)} method.
107
     * @param binaryRoot the ClassPath root of compiled files.
108
     * @return a result object encapsulating the answer (never null)
109
     * @since 1.15
110
     */
111
    public static Result2 findSourceRoots2 (URL binaryRoot) {
112
        checkPreconditions (binaryRoot);
113
        for (SourceForBinaryQueryImplementation impl : implementations.allInstances()) {
114
            Result2 result = null;
115
            if (impl instanceof SourceForBinaryQueryImplementation2) {
116
                SourceForBinaryQueryImplementation2.Result _result = ((SourceForBinaryQueryImplementation2)impl).findSourceRoots2(binaryRoot);
117
                if (_result != null) {                    
118
                    result = new Result2New(_result);
119
                }
120
            }
121
            else {
122
                Result _result = impl.findSourceRoots(binaryRoot);
123
                if (_result != null) {
124
                    result = new Result2(_result);
125
                }
126
            }
127
            if (result != null) {
128
                if (LOG.isLoggable(Level.FINE)) {
129
                    LOG.log(Level.FINE, "findSourceRoots2({0}) -> {1} from {2}", new Object[] {binaryRoot, Arrays.asList(result.getRoots()), impl});
130
                }
131
                return result;
132
            }
133
        }
134
        LOG.log(Level.FINE, "findSourceRoots2({0}) -> nil", binaryRoot);
135
        return EMPTY_RESULT2;
136
        
137
    }
138
    
139
    private static void checkPreconditions (final URL binaryRoot) {
140
        if (FileUtil.isArchiveFile(binaryRoot)) {
141
            throw new IllegalArgumentException("File URL pointing to " + // NOI18N
142
                "JAR is not valid classpath entry. Use jar: URL. Was: "+binaryRoot); // NOI18N
143
        }
144
        if (!binaryRoot.toExternalForm().endsWith("/")) {
145
            throw new IllegalArgumentException ("Folder URL must end with '/'. Was: "+binaryRoot);
146
        }
99
    }
147
    }
100
    
148
    
101
    /**
149
    /**
Lines 124-130 Link Here
124
        
172
        
125
    }
173
    }
126
    
174
    
175
    /**
176
     * Result of finding sources, encapsulating the answer as well as the
177
     * ability to listen to it.
178
     * In addition to the Result it provides information if the source root(s)
179
     * should be preferred over the binaries used by the java infrastructure.
180
     * Most of the clients don't need this information, so thay can use the
181
     * original {@link Result}.
182
     * @since 1.15
183
     */
184
    public static class Result2 implements Result {
185
        
186
        private final Result delegate;
187
        //@GuardedBy(this)
188
        private ChangeListener spiListener;
189
        private final ChangeSupport changeSupport;
190
        
191
        private Result2 (final Result result) {
192
            assert result != null;
193
            this.delegate = result;
194
            this.changeSupport = new ChangeSupport(this);
195
        }
196
197
        public FileObject[] getRoots() {
198
            return this.delegate.getRoots();
199
        }
200
201
        public void addChangeListener(ChangeListener l) {
202
            Parameters.notNull("l", l);     //NOI18N
203
            synchronized (this) {
204
                if (this.spiListener == null) {
205
                    this.spiListener = new ChangeListener() {
206
                        public void stateChanged(ChangeEvent e) {
207
                            changeSupport.fireChange();
208
                        }
209
                    };
210
                    this.delegate.addChangeListener(WeakListeners.change(this.spiListener, this.delegate));
211
                }
212
            }
213
            this.changeSupport.addChangeListener(l);
214
        }
215
216
        public void removeChangeListener(ChangeListener l) {
217
            Parameters.notNull("l", l);
218
            this.changeSupport.removeChangeListener(l);
219
        }
220
221
        /**
222
         * This method is used by the java infrastructure to find out whether the
223
         * sources should be preferred over the binaries.
224
         * @see SourceForBinaryQueryImplementation2
225
         * @return true if sources should be used by the java infrastructure
226
         */
227
        public boolean preferSources() {
228
            //Preserve the old behavior from 4.0 to 6.1, ignore sources inside archives
229
            final FileObject[] roots = this.delegate.getRoots();
230
            for (FileObject root : roots) {
231
                if (FileUtil.getArchiveFile(root) != null) {
232
                    return false;
233
                }
234
            }
235
            return true;
236
        }
237
    }
238
    
239
    private static final class Result2New extends Result2 {
240
        
241
        private final SourceForBinaryQueryImplementation2.Result delegate;
242
        
243
        private Result2New (final SourceForBinaryQueryImplementation2.Result delegate) {
244
            super (delegate);
245
            this.delegate = delegate;
246
        }
247
        
248
        public boolean preferSources() {
249
            return this.delegate.preferSources();
250
        }
251
    }
252
    
127
    private static final Result EMPTY_RESULT = new EmptyResult();
253
    private static final Result EMPTY_RESULT = new EmptyResult();
254
    private static final Result2 EMPTY_RESULT2 = new Result2 (EMPTY_RESULT);
128
    private static final class EmptyResult implements Result {
255
    private static final class EmptyResult implements Result {
129
        private static final FileObject[] NO_ROOTS = new FileObject[0];
256
        private static final FileObject[] NO_ROOTS = new FileObject[0];
130
        EmptyResult() {}
257
        EmptyResult() {}
(-)5e5441c67c62 (+85 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 * 
4
 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
5
 * 
6
 * The contents of this file are subject to the terms of either the GNU
7
 * General Public License Version 2 only ("GPL") or the Common
8
 * Development and Distribution License("CDDL") (collectively, the
9
 * "License"). You may not use this file except in compliance with the
10
 * License. You can obtain a copy of the License at
11
 * http://www.netbeans.org/cddl-gplv2.html
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
 * specific language governing permissions and limitations under the
14
 * License.  When distributing the software, include this License Header
15
 * Notice in each file and include the License file at
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
17
 * particular file as subject to the "Classpath" exception as provided
18
 * by Sun in the GPL Version 2 section of the License file that
19
 * accompanied this code. If applicable, add the following below the
20
 * License Header, with the fields enclosed by brackets [] replaced by
21
 * your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 * 
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 * 
35
 * Contributor(s):
36
 * 
37
 * Portions Copyrighted 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.spi.java.queries;
41
42
import java.net.URL;
43
import org.netbeans.api.java.queries.SourceForBinaryQuery;
44
45
/**
46
 * Information about where Java sources corresponding to binaries
47
 * (classfiles) can be found. 
48
 * <p>
49
 * In addition to the original SourceForBinaryQueryImplementation this interface
50
 * also provides information used by the java infrastructure if sources should be
51
 * preferred over the binaries. When sources are preferred the java infrastructure
52
 * will use sources as a primary source of the metadata otherwise the binaries
53
 * (classfiles) are used as a primary source of information and sources are used
54
 * as a source of formal parameter names and javadoc only.
55
 * In general sources should be preferred for projects which are user editable
56
 * but not for libraries or platforms where the sources may not be complete or 
57
 * up to date.
58
 * </p>
59
 * @see org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation
60
 * @since org.netbeans.api.java/1 1.15
61
 */
62
public interface SourceForBinaryQueryImplementation2 extends SourceForBinaryQueryImplementation {
63
64
    /**
65
     * Returns the source root(s) for a given binary root.
66
     * @see SourceForBinaryQueryImplementation#findSourceRoots(java.net.URL) 
67
     * @param binaryRoot the class path root of Java class files
68
     * @return a result object encapsulating the answer or null if the binaryRoot is not recognized
69
     */
70
    public Result findSourceRoots2 (final URL binaryRoot);
71
    
72
    public static interface Result extends SourceForBinaryQuery.Result {
73
        
74
        /**
75
         * When true the java model prefers sources otherwise binaries are used.
76
         * Project's {@link SourceForBinaryQueryImplementation} should return
77
         * true. The platform and libraries {@link SourceForBinaryQueryImplementation}
78
         * should return false - the attached sources may not be complete.
79
         * @see SourceForBinaryQueryImplementation2
80
         * @return true if sources should be used by the java infrastructure
81
         */
82
        public boolean preferSources();
83
    }
84
    
85
}
(-)a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/query/J2eePlatformSourceForBinaryQuery.java (-6 / +14 lines)
Lines 58-64 Link Here
58
import org.netbeans.modules.j2ee.deployment.impl.ServerRegistry;
58
import org.netbeans.modules.j2ee.deployment.impl.ServerRegistry;
59
import org.netbeans.modules.j2ee.deployment.common.api.J2eeLibraryTypeProvider;
59
import org.netbeans.modules.j2ee.deployment.common.api.J2eeLibraryTypeProvider;
60
import org.netbeans.modules.j2ee.deployment.plugins.spi.J2eePlatformImpl;
60
import org.netbeans.modules.j2ee.deployment.plugins.spi.J2eePlatformImpl;
61
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
61
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2;
62
import org.netbeans.spi.project.libraries.LibraryImplementation;
62
import org.netbeans.spi.project.libraries.LibraryImplementation;
63
import org.openide.filesystems.FileObject;
63
import org.openide.filesystems.FileObject;
64
import org.openide.filesystems.FileStateInvalidException;
64
import org.openide.filesystems.FileStateInvalidException;
Lines 72-87 Link Here
72
 * Finds the locations of sources for various libraries.
72
 * Finds the locations of sources for various libraries.
73
 * @since 1.5
73
 * @since 1.5
74
 */
74
 */
75
public class J2eePlatformSourceForBinaryQuery implements SourceForBinaryQueryImplementation {
75
public class J2eePlatformSourceForBinaryQuery implements SourceForBinaryQueryImplementation2 {
76
76
77
    private final Map/*<URL,SourceForBinaryQuery.Result>*/ cache = new HashMap();
77
    private final Map<URL,SourceForBinaryQueryImplementation2.Result> cache = new HashMap<URL,SourceForBinaryQueryImplementation2.Result>();
78
    private final Map/*<URL,URL>*/ normalizedURLCache = new HashMap();
78
    private final Map/*<URL,URL>*/ normalizedURLCache = new HashMap();
79
79
80
    /** Default constructor for lookup. */
80
    /** Default constructor for lookup. */
81
    public J2eePlatformSourceForBinaryQuery() {}
81
    public J2eePlatformSourceForBinaryQuery() {}
82
82
83
    public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) {
83
    public SourceForBinaryQueryImplementation2.Result findSourceRoots2 (URL binaryRoot) {
84
        SourceForBinaryQuery.Result res = (SourceForBinaryQuery.Result) this.cache.get (binaryRoot);
84
        SourceForBinaryQueryImplementation2.Result res = this.cache.get (binaryRoot);
85
        if (res != null) {
85
        if (res != null) {
86
            return res;
86
            return res;
87
        }
87
        }
Lines 122-127 Link Here
122
        return null;
122
        return null;
123
    }
123
    }
124
    
124
    
125
    public SourceForBinaryQuery.Result findSourceRoots (final URL binaryRoot) {
126
        return this.findSourceRoots2(binaryRoot);
127
    }
128
    
125
    
129
    
126
    private URL getNormalizedURL (URL url) {
130
    private URL getNormalizedURL (URL url) {
127
        //URL is already nornalized, return it
131
        //URL is already nornalized, return it
Lines 160-166 Link Here
160
    }
164
    }
161
    
165
    
162
    
166
    
163
    private static class Result implements SourceForBinaryQuery.Result, PropertyChangeListener {
167
    private static class Result implements SourceForBinaryQueryImplementation2.Result, PropertyChangeListener {
164
        
168
        
165
        private LibraryImplementation lib;
169
        private LibraryImplementation lib;
166
        private URL entry;
170
        private URL entry;
Lines 231-236 Link Here
231
                ((ChangeListener)it.next()).stateChanged(event);
235
                ((ChangeListener)it.next()).stateChanged(event);
232
            }
236
            }
233
        }
237
        }
238
239
        public boolean preferSources() {
240
            return false;
241
        }
234
        
242
        
235
    }
243
    }
236
    
244
    
(-)a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/sharability/SourceForBinaryQueryImpl.java (-6 / +14 lines)
Lines 52-58 Link Here
52
import org.netbeans.api.java.queries.SourceForBinaryQuery;
52
import org.netbeans.api.java.queries.SourceForBinaryQuery;
53
import org.netbeans.api.project.libraries.Library;
53
import org.netbeans.api.project.libraries.Library;
54
import org.netbeans.api.project.libraries.LibraryManager;
54
import org.netbeans.api.project.libraries.LibraryManager;
55
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
55
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2;
56
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
56
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
57
import org.openide.ErrorManager;
57
import org.openide.ErrorManager;
58
import org.openide.filesystems.FileObject;
58
import org.openide.filesystems.FileObject;
Lines 66-86 Link Here
66
 * Finds the locations of sources for various libraries.
66
 * Finds the locations of sources for various libraries.
67
 * @author Tomas Zezula
67
 * @author Tomas Zezula
68
 */
68
 */
69
public class SourceForBinaryQueryImpl implements SourceForBinaryQueryImplementation {
69
public class SourceForBinaryQueryImpl implements SourceForBinaryQueryImplementation2 {
70
70
71
    private static final String[] CLASSPATH_VOLUMES = new String[] {
71
    private static final String[] CLASSPATH_VOLUMES = new String[] {
72
        ServerLibraryTypeProvider.VOLUME_CLASSPATH,
72
        ServerLibraryTypeProvider.VOLUME_CLASSPATH,
73
        ServerLibraryTypeProvider.VOLUME_WS_COMPILE_CLASSPATH
73
        ServerLibraryTypeProvider.VOLUME_WS_COMPILE_CLASSPATH
74
    };
74
    };
75
    
75
    
76
    private final Map<URL,SourceForBinaryQuery.Result> cache = new ConcurrentHashMap<URL,SourceForBinaryQuery.Result>();
76
    private final Map<URL,SourceForBinaryQueryImplementation2.Result> cache = new ConcurrentHashMap<URL,SourceForBinaryQueryImplementation2.Result>();
77
    private final Map<URL,URL> normalizedURLCache = new ConcurrentHashMap<URL,URL>();
77
    private final Map<URL,URL> normalizedURLCache = new ConcurrentHashMap<URL,URL>();
78
78
79
    /** Default constructor for lookup. */
79
    /** Default constructor for lookup. */
80
    public SourceForBinaryQueryImpl() {}
80
    public SourceForBinaryQueryImpl() {}
81
81
82
    public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) {
82
    public SourceForBinaryQueryImplementation2.Result findSourceRoots2(URL binaryRoot) {
83
        SourceForBinaryQuery.Result res = cache.get(binaryRoot);
83
        SourceForBinaryQueryImplementation2.Result res = cache.get(binaryRoot);
84
        if (res != null) {
84
        if (res != null) {
85
            return res;
85
            return res;
86
        }
86
        }
Lines 106-111 Link Here
106
            }
106
            }
107
        }
107
        }
108
        return null;
108
        return null;
109
    }
110
    
111
    public SourceForBinaryQuery.Result findSourceRoots (final URL binaryRoot) {
112
        return this.findSourceRoots2(binaryRoot);
109
    }
113
    }
110
    
114
    
111
    
115
    
Lines 146-152 Link Here
146
    }
150
    }
147
    
151
    
148
    
152
    
149
    private static class Result implements SourceForBinaryQuery.Result, PropertyChangeListener {
153
    private static class Result implements SourceForBinaryQueryImplementation2.Result, PropertyChangeListener {
150
        
154
        
151
        private Library lib;
155
        private Library lib;
152
        private URL entry;
156
        private URL entry;
Lines 205-210 Link Here
205
                cs.fireChange();
209
                cs.fireChange();
206
            }
210
            }
207
        }
211
        }
212
213
        public boolean preferSources() {
214
            return false;
215
        }
208
        
216
        
209
    }
217
    }
210
    
218
    
(-)a/java.j2seplatform/src/org/netbeans/modules/java/j2seplatform/libraries/J2SELibrarySourceForBinaryQuery.java (-7 / +14 lines)
Lines 52-61 Link Here
52
import org.netbeans.api.java.queries.SourceForBinaryQuery;
52
import org.netbeans.api.java.queries.SourceForBinaryQuery;
53
import org.netbeans.api.project.libraries.Library;
53
import org.netbeans.api.project.libraries.Library;
54
import org.netbeans.api.project.libraries.LibraryManager;
54
import org.netbeans.api.project.libraries.LibraryManager;
55
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
55
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2;
56
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
56
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
57
import org.openide.ErrorManager;
57
import org.openide.ErrorManager;
58
import org.openide.filesystems.FileObject;
59
import org.openide.filesystems.FileObject;
58
import org.openide.filesystems.FileObject;
60
import org.openide.filesystems.FileStateInvalidException;
59
import org.openide.filesystems.FileStateInvalidException;
61
import org.openide.filesystems.FileUtil;
60
import org.openide.filesystems.FileUtil;
Lines 67-82 Link Here
67
 * Finds the locations of sources for various libraries.
66
 * Finds the locations of sources for various libraries.
68
 * @author Tomas Zezula
67
 * @author Tomas Zezula
69
 */
68
 */
70
public class J2SELibrarySourceForBinaryQuery implements SourceForBinaryQueryImplementation {
69
public class J2SELibrarySourceForBinaryQuery implements SourceForBinaryQueryImplementation2 {
71
70
72
    private final Map<URL,SourceForBinaryQuery.Result> cache = new ConcurrentHashMap<URL,SourceForBinaryQuery.Result>();
71
    private final Map<URL,SourceForBinaryQueryImplementation2.Result> cache = new ConcurrentHashMap<URL,SourceForBinaryQueryImplementation2.Result>();
73
    private final Map<URL,URL> normalizedURLCache = new ConcurrentHashMap<URL,URL>();
72
    private final Map<URL,URL> normalizedURLCache = new ConcurrentHashMap<URL,URL>();
74
73
75
    /** Default constructor for lookup. */
74
    /** Default constructor for lookup. */
76
    public J2SELibrarySourceForBinaryQuery() {}
75
    public J2SELibrarySourceForBinaryQuery() {}
77
76
78
    public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) {
77
    public SourceForBinaryQueryImplementation2.Result findSourceRoots2 (URL binaryRoot) {
79
        SourceForBinaryQuery.Result res = cache.get(binaryRoot);
78
        SourceForBinaryQueryImplementation2.Result res = cache.get(binaryRoot);
80
        if (res != null) {
79
        if (res != null) {
81
            return res;
80
            return res;
82
        }
81
        }
Lines 101-106 Link Here
101
        return null;
100
        return null;
102
    }
101
    }
103
    
102
    
103
    
104
    public SourceForBinaryQuery.Result findSourceRoots (final URL binaryRoot) {
105
        return this.findSourceRoots2(binaryRoot);
106
    }
104
    
107
    
105
    private URL getNormalizedURL (URL url) {
108
    private URL getNormalizedURL (URL url) {
106
        //URL is already nornalized, return it
109
        //URL is already nornalized, return it
Lines 139-145 Link Here
139
    }
142
    }
140
    
143
    
141
    
144
    
142
    private static class Result implements SourceForBinaryQuery.Result, PropertyChangeListener {
145
    private static class Result implements SourceForBinaryQueryImplementation2.Result, PropertyChangeListener {
143
        
146
        
144
        private Library lib;
147
        private Library lib;
145
        private URL entry;
148
        private URL entry;
Lines 191-196 Link Here
191
                cs.fireChange();
194
                cs.fireChange();
192
            }
195
            }
193
        }
196
        }
197
198
        public boolean preferSources() {
199
            return false;
200
        }
194
        
201
        
195
    }
202
    }
196
    
203
    
(-)a/java.platform/src/org/netbeans/modules/java/platform/queries/PlatformSourceForBinaryQuery.java (-7 / +20 lines)
Lines 55-60 Link Here
55
import org.netbeans.api.java.platform.JavaPlatformManager;
55
import org.netbeans.api.java.platform.JavaPlatformManager;
56
import org.netbeans.api.java.platform.JavaPlatform;
56
import org.netbeans.api.java.platform.JavaPlatform;
57
import org.netbeans.api.java.queries.SourceForBinaryQuery;
57
import org.netbeans.api.java.queries.SourceForBinaryQuery;
58
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2;
58
import org.openide.util.ChangeSupport;
59
import org.openide.util.ChangeSupport;
59
import org.openide.util.Exceptions;
60
import org.openide.util.Exceptions;
60
import org.openide.util.WeakListeners;
61
import org.openide.util.WeakListeners;
Lines 65-77 Link Here
65
 * provides sources for the active platform and project libraries
66
 * provides sources for the active platform and project libraries
66
 */
67
 */
67
68
68
public class PlatformSourceForBinaryQuery implements SourceForBinaryQueryImplementation {
69
public class PlatformSourceForBinaryQuery implements SourceForBinaryQueryImplementation2 {
69
    
70
    
70
    private static final String JAR_FILE = "jar:file:";                 //NOI18N
71
    private static final String JAR_FILE = "jar:file:";                 //NOI18N
71
    private static final String RTJAR_PATH = "/jre/lib/rt.jar!/";       //NOI18N
72
    private static final String RTJAR_PATH = "/jre/lib/rt.jar!/";       //NOI18N
72
    private static final String SRC_ZIP = "/src.zip";                    //NOI18N
73
    private static final String SRC_ZIP = "/src.zip";                    //NOI18N
73
74
74
    private Map<URL,SourceForBinaryQuery.Result> cache = new HashMap<URL,SourceForBinaryQuery.Result>();
75
    private Map<URL,SourceForBinaryQueryImplementation2.Result> cache = new HashMap<URL,SourceForBinaryQueryImplementation2.Result>();
75
76
76
    public PlatformSourceForBinaryQuery () {
77
    public PlatformSourceForBinaryQuery () {
77
    }
78
    }
Lines 81-88 Link Here
81
     * @param binaryRoot the URL of a classpath root (platform supports file and jar protocol)
82
     * @param binaryRoot the URL of a classpath root (platform supports file and jar protocol)
82
     * @return FileObject[], never returns null
83
     * @return FileObject[], never returns null
83
     */
84
     */
84
    public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) {
85
    public SourceForBinaryQueryImplementation2.Result findSourceRoots2(URL binaryRoot) {
85
        SourceForBinaryQuery.Result res = this.cache.get (binaryRoot);
86
        SourceForBinaryQueryImplementation2.Result res = this.cache.get (binaryRoot);
86
        if (res != null) {
87
        if (res != null) {
87
            return res;
88
            return res;
88
        }
89
        }
Lines 115-121 Link Here
115
        return null;
116
        return null;
116
    }
117
    }
117
    
118
    
118
    private static class Result implements SourceForBinaryQuery.Result, PropertyChangeListener {
119
    public SourceForBinaryQuery.Result findSourceRoots (URL binaryRoot) {
120
        return this.findSourceRoots2(binaryRoot);
121
    }
122
    
123
    private static class Result implements SourceForBinaryQueryImplementation2.Result, PropertyChangeListener {
119
                        
124
                        
120
        private JavaPlatform platform;
125
        private JavaPlatform platform;
121
        private final ChangeSupport cs = new ChangeSupport(this);
126
        private final ChangeSupport cs = new ChangeSupport(this);
Lines 145-154 Link Here
145
                cs.fireChange();
150
                cs.fireChange();
146
            }
151
            }
147
        }
152
        }
153
154
        public boolean preferSources() {
155
            return false;
156
        }
148
        
157
        
149
    }
158
    }
150
    
159
    
151
    private static class UnregisteredPlatformResult implements SourceForBinaryQuery.Result {
160
    private static class UnregisteredPlatformResult implements SourceForBinaryQueryImplementation2.Result {
152
        
161
        
153
        private FileObject srcRoot;
162
        private FileObject srcRoot;
154
        
163
        
Lines 168-172 Link Here
168
        public void removeChangeListener(ChangeListener l) {
177
        public void removeChangeListener(ChangeListener l) {
169
            //Not supported, no listening.
178
            //Not supported, no listening.
170
        }
179
        }
171
}}
172
180
181
        public boolean preferSources() {
182
            return false;
183
        }
184
    }}
185
(-)a/java.project/src/org/netbeans/modules/java/project/ExtraProjectSourceForBinaryQueryImpl.java (-6 / +12 lines)
Lines 56-64 Link Here
56
import org.netbeans.api.java.queries.SourceForBinaryQuery;
56
import org.netbeans.api.java.queries.SourceForBinaryQuery;
57
import org.netbeans.api.project.FileOwnerQuery;
57
import org.netbeans.api.project.FileOwnerQuery;
58
import org.netbeans.api.project.Project;
58
import org.netbeans.api.project.Project;
59
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
59
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2;
60
import org.netbeans.spi.project.support.ant.AntProjectHelper;
60
import org.netbeans.spi.project.support.ant.AntProjectHelper;
61
import org.netbeans.spi.project.support.ant.AntProjectListener;
62
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
61
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
63
import org.netbeans.spi.project.support.ant.PropertyUtils;
62
import org.netbeans.spi.project.support.ant.PropertyUtils;
64
import org.netbeans.spi.project.ui.ProjectOpenedHook;
63
import org.netbeans.spi.project.ui.ProjectOpenedHook;
Lines 72-78 Link Here
72
 *
71
 *
73
 * @author mkleint
72
 * @author mkleint
74
 */
73
 */
75
public final class ExtraProjectSourceForBinaryQueryImpl extends ProjectOpenedHook implements SourceForBinaryQueryImplementation {
74
public final class ExtraProjectSourceForBinaryQueryImpl extends ProjectOpenedHook implements SourceForBinaryQueryImplementation2 {
76
75
77
    private static final String REF_START = "file.reference."; //NOI18N
76
    private static final String REF_START = "file.reference."; //NOI18N
78
    private static final String SOURCE_START = "source.reference."; //NOI18N
77
    private static final String SOURCE_START = "source.reference."; //NOI18N
Lines 113-119 Link Here
113
     * @param binaryRoot
112
     * @param binaryRoot
114
     * @return
113
     * @return
115
     */
114
     */
116
    public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) {
115
    public SourceForBinaryQueryImplementation2.Result findSourceRoots2 (URL binaryRoot) {
117
        synchronized (cache) {
116
        synchronized (cache) {
118
            ExtraResult res = cache.get(binaryRoot);
117
            ExtraResult res = cache.get(binaryRoot);
119
            if (res != null) {
118
            if (res != null) {
Lines 126-131 Link Here
126
            }
125
            }
127
        }
126
        }
128
        return null;
127
        return null;
128
    }
129
    
130
    public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) {
131
        return this.findSourceRoots2(binaryRoot);
129
    }
132
    }
130
    
133
    
131
    @Override
134
    @Override
Lines 213-219 Link Here
213
        
216
        
214
    }
217
    }
215
    
218
    
216
    private class ExtraResult implements SourceForBinaryQuery.Result {
219
    private class ExtraResult implements SourceForBinaryQueryImplementation2.Result {
217
        private URL binaryroot;
220
        private URL binaryroot;
218
        private ChangeSupport chs = new ChangeSupport(this);
221
        private ChangeSupport chs = new ChangeSupport(this);
219
        
222
        
Lines 254-260 Link Here
254
        public void removeChangeListener(ChangeListener l) {
257
        public void removeChangeListener(ChangeListener l) {
255
            chs.removeChangeListener(l);
258
            chs.removeChangeListener(l);
256
        }
259
        }
257
        
260
261
        public boolean preferSources() {
262
            return false;
263
        }        
258
    }
264
    }
259
265
260
266
(-)a/java.source/nbproject/project.xml (-9 lines)
Lines 209-223 Link Here
209
                    <run-dependency>
209
                    <run-dependency>
210
                        <release-version>1</release-version>
210
                        <release-version>1</release-version>
211
                        <specification-version>1.5</specification-version>
211
                        <specification-version>1.5</specification-version>
212
                    </run-dependency>
213
                </dependency>
214
                <dependency>
215
                    <code-name-base>org.netbeans.modules.project.libraries</code-name-base>
216
                    <build-prerequisite/>
217
                    <compile-dependency/>
218
                    <run-dependency>
219
                        <release-version>1</release-version>
220
                        <specification-version>1.14</specification-version>
221
                    </run-dependency>
212
                    </run-dependency>
222
                </dependency>
213
                </dependency>
223
                <dependency>
214
                <dependency>
(-)a/java.source/src/org/netbeans/api/java/source/ClassIndex.java (-20 / +16 lines)
Lines 433-460 Link Here
433
        final GlobalSourcePath gsp = GlobalSourcePath.getDefault();
433
        final GlobalSourcePath gsp = GlobalSourcePath.getDefault();
434
        List<ClassPath.Entry> entries = cp.entries();
434
        List<ClassPath.Entry> entries = cp.entries();
435
	for (ClassPath.Entry entry : entries) {
435
	for (ClassPath.Entry entry : entries) {
436
	    try {
436
            URL[] srcRoots;
437
                URL[] srcRoots;
437
            if (!sources) {
438
                if (!sources) {
438
                srcRoots = gsp.getSourceRootForBinaryRoot (entry.getURL(), cp, true);                        
439
                    srcRoots = gsp.getSourceRootForBinaryRoot (entry.getURL(), cp, true);                        
439
                if (srcRoots == null) {
440
                    if (srcRoots == null) {
440
                    srcRoots = new URL[] {entry.getURL()};
441
                        srcRoots = new URL[] {entry.getURL()};
442
                    }
443
                }
441
                }
444
                else {
442
            }
445
                    srcRoots = new URL[] {entry.getURL()};
443
            else {
446
                }                
444
                srcRoots = new URL[] {entry.getURL()};
447
                for (URL srcRoot : srcRoots) {
445
            }                
448
                    oldState.add (srcRoot);
446
            for (URL srcRoot : srcRoots) {
449
                    ClassIndexImpl ci = ClassIndexManager.getDefault().getUsagesQuery(srcRoot);
447
                oldState.add (srcRoot);
450
                    if (ci != null) {
448
                ClassIndexImpl ci = ClassIndexManager.getDefault().getUsagesQuery(srcRoot);
451
                        ci.addClassIndexImplListener(spiListener);
449
                if (ci != null) {
452
                        queries.add (ci);
450
                    ci.addClassIndexImplListener(spiListener);
453
                    }
451
                    queries.add (ci);
454
                }
452
                }
455
	    } catch (IOException ioe) {
453
            }	    
456
		Exceptions.printStackTrace(ioe);
457
	    }
458
	}
454
	}
459
    }
455
    }
460
    
456
    
(-)a/java.source/src/org/netbeans/api/java/source/ClasspathInfo.java (-1 / +1 lines)
Lines 111-117 Link Here
111
        this.cachedCompileClassPath = CacheClassPath.forClassPath(this.compileClassPath);
111
        this.cachedCompileClassPath = CacheClassPath.forClassPath(this.compileClassPath);
112
	this.cachedBootClassPath.addPropertyChangeListener(WeakListeners.propertyChange(this.cpListener,this.cachedBootClassPath));
112
	this.cachedBootClassPath.addPropertyChangeListener(WeakListeners.propertyChange(this.cpListener,this.cachedBootClassPath));
113
	this.cachedCompileClassPath.addPropertyChangeListener(WeakListeners.propertyChange(this.cpListener,this.cachedCompileClassPath));
113
	this.cachedCompileClassPath.addPropertyChangeListener(WeakListeners.propertyChange(this.cpListener,this.cachedCompileClassPath));
114
	if ( srcCp != null && !GlobalSourcePath.getDefault().isLibrary(srcCp)) {
114
	if ( srcCp != null && (backgroundCompilation || !GlobalSourcePath.getDefault().isLibrary(srcCp))) {
115
            this.srcClassPath = srcCp;
115
            this.srcClassPath = srcCp;
116
            this.outputClassPath = CacheClassPath.forSourcePath (this.srcClassPath);
116
            this.outputClassPath = CacheClassPath.forSourcePath (this.srcClassPath);
117
	    this.srcClassPath.addPropertyChangeListener(WeakListeners.propertyChange(this.cpListener,this.srcClassPath));
117
	    this.srcClassPath.addPropertyChangeListener(WeakListeners.propertyChange(this.cpListener,this.srcClassPath));
(-)a/java.source/src/org/netbeans/modules/java/source/classpath/GlobalSourcePath.java (-187 / +38 lines)
Lines 44-53 Link Here
44
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeEvent;
45
import java.beans.PropertyChangeListener;
45
import java.beans.PropertyChangeListener;
46
import java.lang.ref.WeakReference;
46
import java.lang.ref.WeakReference;
47
import java.net.URISyntaxException;
48
import java.net.URL;
47
import java.net.URL;
49
import java.util.ArrayList;
48
import java.util.ArrayList;
50
import java.util.Arrays;
51
import java.util.Collection;
49
import java.util.Collection;
52
import java.util.Collections;
50
import java.util.Collections;
53
import java.util.HashMap;
51
import java.util.HashMap;
Lines 58-89 Link Here
58
import java.util.Set;
56
import java.util.Set;
59
import java.util.TooManyListenersException;
57
import java.util.TooManyListenersException;
60
import java.util.concurrent.CopyOnWriteArrayList;
58
import java.util.concurrent.CopyOnWriteArrayList;
61
import java.util.logging.Logger;
62
import javax.swing.event.ChangeEvent;
59
import javax.swing.event.ChangeEvent;
63
import javax.swing.event.ChangeListener;
60
import javax.swing.event.ChangeListener;
64
import org.netbeans.api.java.classpath.ClassPath;
61
import org.netbeans.api.java.classpath.ClassPath;
65
import org.netbeans.api.java.classpath.GlobalPathRegistry;
62
import org.netbeans.api.java.classpath.GlobalPathRegistry;
66
import org.netbeans.api.java.classpath.GlobalPathRegistryEvent;
63
import org.netbeans.api.java.classpath.GlobalPathRegistryEvent;
67
import org.netbeans.api.java.classpath.GlobalPathRegistryListener;
64
import org.netbeans.api.java.classpath.GlobalPathRegistryListener;
68
import org.netbeans.api.java.platform.JavaPlatform;
69
import org.netbeans.api.java.platform.JavaPlatformManager;
70
import org.netbeans.api.java.queries.SourceForBinaryQuery;
65
import org.netbeans.api.java.queries.SourceForBinaryQuery;
71
import org.netbeans.api.project.FileOwnerQuery;
66
import org.netbeans.modules.java.source.usages.ClassIndexManager;
72
import org.netbeans.api.project.Project;
73
import org.netbeans.api.project.ProjectManager;
74
import org.netbeans.api.project.SourceGroup;
75
import org.netbeans.api.project.Sources;
76
import org.netbeans.api.project.libraries.Library;
77
import org.netbeans.api.project.libraries.LibraryManager;
78
import org.netbeans.spi.java.classpath.ClassPathImplementation;
67
import org.netbeans.spi.java.classpath.ClassPathImplementation;
79
import org.netbeans.spi.java.classpath.PathResourceImplementation;
68
import org.netbeans.spi.java.classpath.PathResourceImplementation;
80
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
69
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
81
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
82
import org.openide.ErrorManager;
83
import org.openide.filesystems.FileObject;
70
import org.openide.filesystems.FileObject;
84
import org.openide.filesystems.FileStateInvalidException;
71
import org.openide.filesystems.FileStateInvalidException;
85
import org.openide.util.Exceptions;
72
import org.openide.util.Exceptions;
86
import org.openide.util.Mutex;
87
import org.openide.util.RequestProcessor;
73
import org.openide.util.RequestProcessor;
88
import org.openide.util.Utilities;
74
import org.openide.util.Utilities;
89
import org.openide.util.WeakListeners;
75
import org.openide.util.WeakListeners;
Lines 116-130 Link Here
116
    private final BinaryPathImplementation binaryPath;
102
    private final BinaryPathImplementation binaryPath;
117
    private final UnknownSourcePathImplementation unknownSourcePath;
103
    private final UnknownSourcePathImplementation unknownSourcePath;
118
    
104
    
119
    private final JavaPlatformManager pm;
120
    private Set<JavaPlatform> seenPlatforms;
121
    private Set<Library> seenLibs;
122
    private Collection<LibraryManager> seenLibManagers;
123
    
124
    private Set<URL> libsSrcs;
125
    
126
    private final Listener listener;
105
    private final Listener listener;
127
    private final LibsListener libsListener;
128
    
106
    
129
    private volatile PropertyChangeListener excludesListener;
107
    private volatile PropertyChangeListener excludesListener;
130
108
Lines 140-153 Link Here
140
        this.sourceResults = Collections.emptyMap();
118
        this.sourceResults = Collections.emptyMap();
141
        this.unknownRoots = new HashMap<URL, WeakValue>();
119
        this.unknownRoots = new HashMap<URL, WeakValue>();
142
        this.translatedRoots = new HashMap<URL, URL[]> ();
120
        this.translatedRoots = new HashMap<URL, URL[]> ();
143
        this.gpr.addGlobalPathRegistryListener ((GlobalPathRegistryListener)WeakListeners.create(GlobalPathRegistryListener.class,this.listener,this.gpr));        
121
        this.gpr.addGlobalPathRegistryListener ((GlobalPathRegistryListener)WeakListeners.create(GlobalPathRegistryListener.class,this.listener,this.gpr));
144
        this.seenPlatforms = new HashSet<JavaPlatform>();
145
        this.seenLibs = new HashSet<Library> ();
146
        this.seenLibManagers = new HashSet<LibraryManager>();
147
        this.libsListener = new LibsListener ();
148
        LibraryManager.addOpenManagersPropertyChangeListener(WeakListeners.propertyChange(libsListener, null));
149
        this.pm = JavaPlatformManager.getDefault();
150
        this.pm.addPropertyChangeListener(WeakListeners.propertyChange(libsListener, this.pm));
151
    }
122
    }
152
    
123
    
153
    
124
    
Lines 170-176 Link Here
170
        } 
141
        } 
171
        else {
142
        else {
172
            List<URL> cacheRoots = new ArrayList<URL> ();
143
            List<URL> cacheRoots = new ArrayList<URL> ();
173
            Collection<? extends PathResourceImplementation> unknownRes = getSources(SourceForBinaryQuery.findSourceRoots(binaryRoot).getRoots(),cacheRoots,null);
144
            Collection<? extends PathResourceImplementation> unknownRes = getSources(SourceForBinaryQuery.findSourceRoots2(binaryRoot),cacheRoots,null);
174
            if (unknownRes.isEmpty()) {
145
            if (unknownRes.isEmpty()) {
175
                return null;
146
                return null;
176
            }
147
            }
Lines 193-211 Link Here
193
    
164
    
194
    public boolean isLibrary (final ClassPath cp) {
165
    public boolean isLibrary (final ClassPath cp) {
195
        assert cp != null;
166
        assert cp != null;
196
        Set<URL> libs = getLibsSources();
167
        final ClassIndexManager mgr = ClassIndexManager.getDefault();
197
        for (ClassPath.Entry entry : cp.entries()) {
168
        for (FileObject fo : cp.getRoots()) {
198
            if (libs.contains(entry.getURL())) {
169
            if (isLibrary (fo)) {
199
                return true;
170
                return true;
200
            }
171
            }
201
        }
172
        }
202
        return false;
173
        return false;
203
    }
174
    }
204
    
175
    
205
    public boolean isLibrary (final URL root) {
176
    public boolean isLibrary (final FileObject root) {
206
        assert root != null;
177
        assert root != null;
207
        Set<URL> libs = getLibsSources();
178
        try {
208
        return libs.contains(root);
179
            return ClassIndexManager.getDefault().getUsagesQuery(root.getURL()) == null;
180
        } catch (FileStateInvalidException e) {
181
            Exceptions.printStackTrace(e);
182
            return true;    //Safer
183
        }
209
    }
184
    }
210
    
185
    
211
    public ClassPathImplementation getSourcePath () {
186
    public ClassPathImplementation getSourcePath () {
Lines 260-269 Link Here
260
            for (ClassPath.Entry entry : cp.entries()) {
235
            for (ClassPath.Entry entry : cp.entries()) {
261
                URL url = entry.getURL();
236
                URL url = entry.getURL();
262
                if (!translatedRoots.containsKey(url)) {
237
                if (!translatedRoots.containsKey(url)) {
263
                    SourceForBinaryQuery.Result sr = r.oldSR.remove (url);
238
                    SourceForBinaryQuery.Result2 sr = r.oldSR.remove (url);
264
                    boolean isNewSR;
239
                    boolean isNewSR;
265
                    if (sr == null) {
240
                    if (sr == null) {
266
                        sr = SourceForBinaryQuery.findSourceRoots(url);
241
                        sr = SourceForBinaryQuery.findSourceRoots2(url);
267
                        isNewSR = true;                    
242
                        isNewSR = true;                    
268
                    }
243
                    }
269
                    else {
244
                    else {
Lines 272-278 Link Here
272
                    assert !newSR.containsKey(url);
247
                    assert !newSR.containsKey(url);
273
                    newSR.put(url,sr);
248
                    newSR.put(url,sr);
274
                    List<URL> cacheURLs = new ArrayList<URL> ();
249
                    List<URL> cacheURLs = new ArrayList<URL> ();
275
                    Collection<? extends PathResourceImplementation> srcRoots = getSources (sr.getRoots(), cacheURLs, r.unknownRoots);
250
                    Collection<? extends PathResourceImplementation> srcRoots = getSources (sr, cacheURLs, r.unknownRoots);
276
                    if (srcRoots.isEmpty()) {
251
                    if (srcRoots.isEmpty()) {
277
                        binaryResult.add (ClassPathSupport.createResource(url));
252
                        binaryResult.add (ClassPathSupport.createResource(url));
278
                    }
253
                    }
Lines 296-305 Link Here
296
            for (ClassPath.Entry entry : cp.entries()) {
271
            for (ClassPath.Entry entry : cp.entries()) {
297
                URL url = entry.getURL();
272
                URL url = entry.getURL();
298
                if (!translatedRoots.containsKey(url)) {
273
                if (!translatedRoots.containsKey(url)) {
299
                    SourceForBinaryQuery.Result sr = r.oldSR.remove (url);
274
                    SourceForBinaryQuery.Result2 sr = r.oldSR.remove (url);
300
                    boolean isNewSR;
275
                    boolean isNewSR;
301
                    if (sr == null) {
276
                    if (sr == null) {
302
                        sr = SourceForBinaryQuery.findSourceRoots(url);
277
                        sr = SourceForBinaryQuery.findSourceRoots2(url);
303
                        isNewSR = true;                    
278
                        isNewSR = true;                    
304
                    }
279
                    }
305
                    else {
280
                    else {
Lines 308-314 Link Here
308
                    assert !newSR.containsKey(url);
283
                    assert !newSR.containsKey(url);
309
                    newSR.put(url,sr);
284
                    newSR.put(url,sr);
310
                    List<URL> cacheURLs = new ArrayList<URL> ();
285
                    List<URL> cacheURLs = new ArrayList<URL> ();
311
                    Collection<? extends PathResourceImplementation> srcRoots = getSources(sr.getRoots(),cacheURLs, r.unknownRoots);
286
                    Collection<? extends PathResourceImplementation> srcRoots = getSources(sr,cacheURLs, r.unknownRoots);
312
                    if (srcRoots.isEmpty()) {
287
                    if (srcRoots.isEmpty()) {
313
                        binaryResult.add(ClassPathSupport.createResource(url));
288
                        binaryResult.add(ClassPathSupport.createResource(url));
314
                    }
289
                    }
Lines 331-337 Link Here
331
            cp.removePropertyChangeListener(r.propertyListener);
306
            cp.removePropertyChangeListener(r.propertyListener);
332
        }
307
        }
333
        
308
        
334
        for (Map.Entry<URL,SourceForBinaryQuery.Result> entry : r.oldSR.entrySet()) {
309
        for (Map.Entry<URL,SourceForBinaryQuery.Result2> entry : r.oldSR.entrySet()) {
335
            entry.getValue().removeChangeListener(r.changeListener);
310
            entry.getValue().removeChangeListener(r.changeListener);
336
        }                        
311
        }                        
337
        for (URL unknownRoot : r.unknownRoots.keySet()) {
312
        for (URL unknownRoot : r.unknownRoots.keySet()) {
Lines 377-521 Link Here
377
        }
352
        }
378
    }
353
    }
379
    
354
    
380
    private Collection <? extends PathResourceImplementation> getSources (final FileObject[] roots, final List<URL> cacheDirs, final Map<URL, WeakValue> unknownRoots) {
355
    private Collection <? extends PathResourceImplementation> getSources (final SourceForBinaryQuery.Result2 sr, final List<URL> cacheDirs, final Map<URL, WeakValue> unknownRoots) {
381
        assert roots != null;        
356
        assert sr != null;
382
        URL[] urls = new URL[roots.length];
357
        if (sr.preferSources()) {
383
        boolean add = true;
358
            final FileObject[] roots = sr.getRoots();
384
        Set<URL> libs = getLibsSources();
359
            assert roots != null;
385
        for (int i=0; i<roots.length; i++) {
386
            try {
387
                URL url = roots[i].getURL();
388
                if (!"file".equals(url.getProtocol())) {     //NOI18N
389
                    add = false;
390
                    break;
391
                }
392
                if (libs.contains (url)) {
393
                    add = false;
394
                    break;
395
                }
396
                urls[i] = url;
397
            } catch (FileStateInvalidException e) {
398
                ErrorManager.getDefault().notify(e);
399
            }
400
        }        
401
        if (add) {
402
            List<PathResourceImplementation> result = new ArrayList<PathResourceImplementation> (roots.length);
360
            List<PathResourceImplementation> result = new ArrayList<PathResourceImplementation> (roots.length);
403
            for (int i=0; i<urls.length; i++) {
361
            for (int i=0; i<roots.length; i++) {
362
                try {
363
                final URL url = roots[i].getURL();
404
                if (cacheDirs != null) {
364
                if (cacheDirs != null) {
405
                    cacheDirs.add (urls[i]);                        
365
                    cacheDirs.add (url);                        
406
                }
366
                }
407
                if (unknownRoots != null) {
367
                if (unknownRoots != null) {
408
                    unknownRoots.remove (urls[i]);
368
                    unknownRoots.remove (url);
409
                }
369
                }
410
                result.add(ClassPathSupport.createResource(urls[i]));
370
                result.add(ClassPathSupport.createResource(url));
371
                } catch (FileStateInvalidException e) {
372
                    Exceptions.printStackTrace(e);
373
                }
411
            }
374
            }
412
            return result;
375
            return result;
413
        }
376
        }
414
        return Collections.<PathResourceImplementation>emptySet();
377
        else {
415
    }
378
            return Collections.<PathResourceImplementation>emptySet();
416
    
417
    private Set<URL> getLibsSources () {
418
        if (!useLibraries) {
419
            //Running in the test where libraries modules SPI is not initialized
420
            return Collections.<URL>emptySet();
421
        }
379
        }
422
        // retrieve list outside of java mutex:
423
        final Collection<LibraryManager> libraryManagers = LibraryManager.getOpenManagers();
424
        final Mutex.Action<Set<URL>> libsTask = new Mutex.Action<Set<URL>> () {
425
            public Set<URL> run () {
426
                synchronized (GlobalSourcePath.this) {
427
                    if (GlobalSourcePath.this.libsSrcs == null) {
428
                        final Set<URL> _libSrcs = new HashSet<URL>();
429
                        Set<JavaPlatform> platforms = new HashSet<JavaPlatform> (Arrays.asList(pm.getInstalledPlatforms()));
430
                        Set<JavaPlatform> oldPlatforms = new HashSet<JavaPlatform> (GlobalSourcePath.this.seenPlatforms);
431
                        OUTER: for (JavaPlatform platform : platforms) {                
432
                            if (!oldPlatforms.remove(platform)) {
433
                                platform.addPropertyChangeListener(GlobalSourcePath.this.libsListener);
434
                            }
435
                            ClassPath cp = platform.getSourceFolders();
436
                            assert cp != null : platform.getClass();
437
                            for (ClassPath.Entry e : cp.entries()) {
438
                                URL url = e.getURL();
439
                                try {
440
                                    Project p = FileOwnerQuery.getOwner(url.toURI());
441
                                    if (p != null) {
442
                                        Sources src = p.getLookup().lookup(Sources.class);
443
                                        if (src != null) {
444
                                            for (SourceGroup group : src.getSourceGroups("java")) {        //NOI18N
445
                                                if (url.equals(group.getRootFolder().getURL())) {
446
                                                    continue OUTER;
447
                                                }
448
                                            }
449
                                        }
450
                                    }
451
                                } catch (URISyntaxException ex) {
452
                                    Exceptions.printStackTrace(ex);
453
                                }
454
                                catch (FileStateInvalidException ex) {
455
                                    Exceptions.printStackTrace(ex);
456
                                }
457
                                _libSrcs.add(url);
458
                            }
459
                        }
460
                        for (JavaPlatform platform : oldPlatforms) {
461
                            platform.removePropertyChangeListener(GlobalSourcePath.this.libsListener);
462
                        }
463
                        GlobalSourcePath.this.seenPlatforms = platforms;
464
465
                        for (LibraryManager lm : GlobalSourcePath.this.seenLibManagers) {
466
                            lm.removePropertyChangeListener(libsListener);
467
                        }
468
                        Set<Library> oldLibs = new HashSet<Library>(GlobalSourcePath.this.seenLibs);
469
                        Set<Library> newLibs = new HashSet<Library>();
470
                        for (LibraryManager lm : libraryManagers) {
471
                            lm.addPropertyChangeListener(libsListener);
472
473
                            Set<Library> libs = new HashSet<Library> (Arrays.asList(lm.getLibraries()));
474
                            OUTER: for (Library lib :libs) {
475
                                newLibs.add(lib);
476
                                if (!oldLibs.remove(lib)) {
477
                                    lib.addPropertyChangeListener(GlobalSourcePath.this.libsListener);
478
                                }
479
                                if (lib.getContent("classpath") != null) {      //NOI18N
480
                                    List<URL> libSrc = lib.getContent("src");      //NOI18N
481
                                    for (URL url : libSrc) {                        
482
                                        try {
483
                                            url = LibrariesSupport.resolveLibraryEntryURL(lm.getLocation(), url);
484
                                            Project p = FileOwnerQuery.getOwner(url.toURI());
485
                                            if (p != null) {
486
                                                Sources src = p.getLookup().lookup(Sources.class);
487
                                                if (src != null) {
488
                                                    for (SourceGroup group : src.getSourceGroups("java")) {        //NOI18N
489
                                                        if (url.equals(group.getRootFolder().getURL())) {
490
                                                            continue OUTER;
491
                                                        }
492
                                                    }
493
                                                }
494
                                            }
495
                                        } catch (URISyntaxException ex) {
496
                                            Exceptions.printStackTrace(ex);
497
                                        }
498
                                        catch (FileStateInvalidException ex) {
499
                                            Exceptions.printStackTrace(ex);
500
                                        }                        
501
                                        _libSrcs.add(url);
502
                                    }
503
504
                                }
505
                            }
506
                        }
507
                        for (Library lib : oldLibs) {
508
                            lib.removePropertyChangeListener(GlobalSourcePath.this.libsListener);
509
                        }
510
                        GlobalSourcePath.this.seenLibManagers = libraryManagers;
511
                        GlobalSourcePath.this.seenLibs = newLibs;
512
                        GlobalSourcePath.this.libsSrcs = _libSrcs;
513
                    }
514
                    return GlobalSourcePath.this.libsSrcs;
515
                }
516
            }
517
        };
518
        return ProjectManager.mutex().readAccess(libsTask);
519
    }
380
    }
520
       
381
       
521
    private class WeakValue extends WeakReference<ClassPath> implements Runnable {
382
    private class WeakValue extends WeakReference<ClassPath> implements Runnable {
Lines 550-562 Link Here
550
        final Set<ClassPath> bootCps;
411
        final Set<ClassPath> bootCps;
551
        final Set<ClassPath> compileCps;
412
        final Set<ClassPath> compileCps;
552
        final Set<ClassPath> oldCps;
413
        final Set<ClassPath> oldCps;
553
        final Map <URL, SourceForBinaryQuery.Result> oldSR;
414
        final Map <URL, SourceForBinaryQuery.Result2> oldSR;
554
        final Map<URL, WeakValue> unknownRoots;
415
        final Map<URL, WeakValue> unknownRoots;
555
        final PropertyChangeListener propertyListener;
416
        final PropertyChangeListener propertyListener;
556
        final ChangeListener changeListener;
417
        final ChangeListener changeListener;
557
        
418
        
558
        public Request (final long timeStamp, final Set<ClassPath> sourceCps, final Set<ClassPath> bootCps, final Set<ClassPath> compileCps,
419
        public Request (final long timeStamp, final Set<ClassPath> sourceCps, final Set<ClassPath> bootCps, final Set<ClassPath> compileCps,
559
            final Set<ClassPath> oldCps, final Map <URL, SourceForBinaryQuery.Result> oldSR, final Map<URL, WeakValue> unknownRoots,
420
            final Set<ClassPath> oldCps, final Map <URL, SourceForBinaryQuery.Result2> oldSR, final Map<URL, WeakValue> unknownRoots,
560
            final PropertyChangeListener propertyListener, final ChangeListener changeListener) {
421
            final PropertyChangeListener propertyListener, final ChangeListener changeListener) {
561
            assert sourceCps != null;
422
            assert sourceCps != null;
562
            assert bootCps != null;
423
            assert bootCps != null;
Lines 867-882 Link Here
867
            }
728
            }
868
    }
729
    }
869
    
730
    
870
    private class LibsListener implements PropertyChangeListener {
871
872
        public void propertyChange(PropertyChangeEvent evt) {
873
            synchronized (GlobalSourcePath.this) {
874
                GlobalSourcePath.this.libsSrcs = null;
875
            }
876
        }
877
        
878
    }
879
    
880
    public static synchronized GlobalSourcePath getDefault () {
731
    public static synchronized GlobalSourcePath getDefault () {
881
        if (instance == null) {
732
        if (instance == null) {
882
            instance = new GlobalSourcePath ();
733
            instance = new GlobalSourcePath ();
(-)a/java.source/src/org/netbeans/modules/java/source/usages/ClassIndexManager.java (-1 / +1 lines)
Lines 141-147 Link Here
141
        return Thread.currentThread().equals(this.owner);
141
        return Thread.currentThread().equals(this.owner);
142
    }
142
    }
143
    
143
    
144
    public synchronized ClassIndexImpl getUsagesQuery (final URL root) throws IOException {
144
    public synchronized ClassIndexImpl getUsagesQuery (final URL root) {
145
        assert root != null;
145
        assert root != null;
146
        if (invalid) {
146
        if (invalid) {
147
            return null;
147
            return null;
(-)a/java.source/src/org/netbeans/modules/java/source/usages/RepositoryUpdater.java (-1 / +1 lines)
Lines 551-557 Link Here
551
    public final void scheduleCompilation (final FileObject fo, final FileObject root) throws IOException {
551
    public final void scheduleCompilation (final FileObject fo, final FileObject root) throws IOException {
552
        URL foURL = fo.getURL();
552
        URL foURL = fo.getURL();
553
        URL rootURL = root.getURL();
553
        URL rootURL = root.getURL();
554
        if (!cpImpl.isLibrary(rootURL)) {
554
        if (!cpImpl.isLibrary(root)) {
555
            assert "file".equals(foURL.getProtocol()) && "file".equals(rootURL.getProtocol());
555
            assert "file".equals(foURL.getProtocol()) && "file".equals(rootURL.getProtocol());
556
            scheduleCompilation (foURL,rootURL,fo.isFolder());
556
            scheduleCompilation (foURL,rootURL,fo.isFolder());
557
        }        
557
        }        

Return to bug 128695