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

(-)maven/src/org/netbeans/modules/maven/queries/AbstractMavenForBinaryQueryImpl.java (+168 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 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 2008 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.maven.queries;
44
45
import java.net.URI;
46
import java.net.URL;
47
import java.util.Collection;
48
import java.util.LinkedHashSet;
49
import org.netbeans.api.annotations.common.CheckForNull;
50
import org.netbeans.api.annotations.common.NullAllowed;
51
import org.netbeans.api.annotations.common.SuppressWarnings;
52
import org.netbeans.modules.maven.NbMavenProjectImpl;
53
import org.netbeans.modules.maven.api.FileUtilities;
54
import org.netbeans.api.java.queries.SourceForBinaryQuery;
55
import org.netbeans.api.project.Project;
56
import org.netbeans.modules.maven.spi.queries.JavaLikeRootProvider;
57
import org.netbeans.spi.java.queries.JavadocForBinaryQueryImplementation;
58
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2;
59
import org.openide.filesystems.FileObject;
60
import org.openide.filesystems.FileUtil;
61
62
63
/**
64
 * SourceForBinary and JavadocForBinary query impls.
65
 * @author  Milos Kleint 
66
 */
67
abstract class AbstractMavenForBinaryQueryImpl implements SourceForBinaryQueryImplementation2,
68
        JavadocForBinaryQueryImplementation {
69
    
70
71
   
72
    protected AbstractMavenForBinaryQueryImpl() {
73
    }
74
75
    public @Override SourceForBinaryQuery.Result findSourceRoots(URL url) {
76
        return findSourceRoots2(url);
77
    }
78
79
80
    static @CheckForNull String jarify(@NullAllowed String path) { // #200088
81
        return path != null ? path.replaceFirst("[.][^./]+$", ".jar") : null;
82
    }
83
    
84
    static FileObject[] getProjectSrcRoots(Project p) {
85
        NbMavenProjectImpl project = p.getLookup().lookup(NbMavenProjectImpl.class);
86
        Collection<FileObject> toReturn = new LinkedHashSet<FileObject>();
87
        for (String item : project.getOriginalMavenProject().getCompileSourceRoots()) {
88
            FileObject fo = FileUtilities.convertStringToFileObject(item);
89
            if (fo != null) {
90
                toReturn.add(fo);
91
            }
92
        }
93
        for (URI genRoot : project.getGeneratedSourceRoots(false)) {
94
            FileObject fo = FileUtilities.convertURItoFileObject(genRoot);
95
            if (fo != null) {
96
                toReturn.add(fo);
97
            }
98
        }
99
        for (JavaLikeRootProvider rp : project.getLookup().lookupAll(JavaLikeRootProvider.class)) {
100
            FileObject fo = project.getProjectDirectory().getFileObject("src/main/" + rp.kind());
101
            if (fo != null) {
102
                toReturn.add(fo);
103
            }
104
        }
105
106
        URI[] res = project.getResources(false);
107
        for (int i = 0; i < res.length; i++) {
108
            FileObject fo = FileUtilities.convertURItoFileObject(res[i]);
109
            if (fo != null) {
110
                boolean ok = true;
111
                //#166655 resource root cannot contain the real java/xxx roots
112
                for (FileObject form : toReturn) {
113
                    if (FileUtil.isParentOf(fo, form)) {
114
                        ok = false;
115
                        break;
116
                    }
117
                }
118
                if (ok) {
119
                    toReturn.add(fo);
120
                }
121
            }
122
        }
123
        return toReturn.toArray(new FileObject[toReturn.size()]);
124
    }
125
    
126
    static FileObject[] getProjectTestSrcRoots(Project p) {
127
        NbMavenProjectImpl project = p.getLookup().lookup(NbMavenProjectImpl.class);
128
        Collection<FileObject> toReturn = new LinkedHashSet<FileObject>();
129
        for (String item : project.getOriginalMavenProject().getTestCompileSourceRoots()) {
130
            FileObject fo = FileUtilities.convertStringToFileObject(item);
131
            if (fo != null) {
132
                toReturn.add(fo);
133
            }
134
        }
135
        for (URI genRoot : project.getGeneratedSourceRoots(true)) {
136
            FileObject fo = FileUtilities.convertURItoFileObject(genRoot);
137
            if (fo != null) {
138
                toReturn.add(fo);
139
            }
140
        }
141
        for (JavaLikeRootProvider rp : project.getLookup().lookupAll(JavaLikeRootProvider.class)) {
142
            FileObject fo = project.getProjectDirectory().getFileObject("src/test/" + rp.kind());
143
            if (fo != null) {
144
                toReturn.add(fo);
145
            }
146
        }
147
148
        URI[] res = project.getResources(true);
149
        for (int i = 0; i < res.length; i++) {
150
            FileObject fo = FileUtilities.convertURItoFileObject(res[i]);
151
            if (fo != null) {
152
                boolean ok = true;
153
                //#166655 resource root cannot contain the real java/xxx roots
154
                for (FileObject form : toReturn) {
155
                    if (FileUtil.isParentOf(fo, form)) {
156
                        ok = false;
157
                        break;
158
                    }
159
                }
160
                if (ok) {
161
                    toReturn.add(fo);
162
                }
163
            }
164
        }
165
        return toReturn.toArray(new FileObject[toReturn.size()]);
166
    }
167
    
168
}
(-)maven/src/org/netbeans/modules/maven/queries/MavenFileOwnerQueryImpl.java (-4 / +8 lines)
Lines 71-76 Link Here
71
import org.openide.util.ChangeSupport;
71
import org.openide.util.ChangeSupport;
72
import org.openide.util.Lookup;
72
import org.openide.util.Lookup;
73
import org.openide.util.NbPreferences;
73
import org.openide.util.NbPreferences;
74
import org.openide.util.WeakListeners;
74
import org.openide.util.lookup.ServiceProvider;
75
import org.openide.util.lookup.ServiceProvider;
75
import org.openide.util.lookup.ServiceProviders;
76
import org.openide.util.lookup.ServiceProviders;
76
77
Lines 106-111 Link Here
106
        project.getProjectWatcher().addPropertyChangeListener(projectListener);       
107
        project.getProjectWatcher().addPropertyChangeListener(projectListener);       
107
    }
108
    }
108
109
110
    public static String cacheKey(String groupId, String artifactId, String version) {
111
        return groupId + ':' + artifactId + ":" + version;
112
    }
113
109
    public void registerCoordinates(String groupId, String artifactId, String version, URL owner) {
114
    public void registerCoordinates(String groupId, String artifactId, String version, URL owner) {
110
        String oldkey = groupId + ':' + artifactId;
115
        String oldkey = groupId + ':' + artifactId;
111
        //remove old key if pointing to the same project
116
        //remove old key if pointing to the same project
Lines 113-119 Link Here
113
            prefs().remove(oldkey);
118
            prefs().remove(oldkey);
114
        }
119
        }
115
        
120
        
116
        String key = oldkey + ":" + version;
121
        String key = cacheKey(groupId, artifactId, version);
117
        String prevKey = reversePrefs().get(owner.toString(), null);
122
        String prevKey = reversePrefs().get(owner.toString(), null);
118
        if (prevKey != null && !prevKey.equals(key)) {
123
        if (prevKey != null && !prevKey.equals(key)) {
119
            prefs().remove(prevKey);
124
            prefs().remove(prevKey);
Lines 228-234 Link Here
228
    public Project getOwner(String groupId, String artifactId, String version) {
233
    public Project getOwner(String groupId, String artifactId, String version) {
229
        LOG.log(Level.FINER, "Checking {0} / {1} / {2}", new Object[] {groupId, artifactId, version});
234
        LOG.log(Level.FINER, "Checking {0} / {1} / {2}", new Object[] {groupId, artifactId, version});
230
        String oldKey = groupId + ":" + artifactId;
235
        String oldKey = groupId + ":" + artifactId;
231
        String key = oldKey + ":" + version;
236
        String key = cacheKey(groupId, artifactId, version);
232
        String ownerURI = prefs().get(key, null);
237
        String ownerURI = prefs().get(key, null);
233
        boolean usingOldKey = false;
238
        boolean usingOldKey = false;
234
        if (ownerURI == null) {
239
        if (ownerURI == null) {
Lines 282-288 Link Here
282
                } else {
287
                } else {
283
                    prefs().remove(key); // stale    
288
                    prefs().remove(key); // stale    
284
                }
289
                }
285
                //TODO fire change..
286
            }
290
            }
287
        } else {
291
        } else {
288
            LOG.log(Level.FINE, "No known owner for {0}", key);
292
            LOG.log(Level.FINE, "No known owner for {0}", key);
Lines 293-299 Link Here
293
    public File getOwnerPOM(String groupId, String artifactId, String version) {
297
    public File getOwnerPOM(String groupId, String artifactId, String version) {
294
        LOG.log(Level.FINER, "Checking {0} / {1} / {2} (POM only)", new Object[] {groupId, artifactId, version});
298
        LOG.log(Level.FINER, "Checking {0} / {1} / {2} (POM only)", new Object[] {groupId, artifactId, version});
295
        String oldKey = groupId + ":" + artifactId;
299
        String oldKey = groupId + ":" + artifactId;
296
        String key = oldKey + ":" + version;
300
        String key = cacheKey(groupId, artifactId, version);
297
        String ownerURI = prefs().get(key, null);
301
        String ownerURI = prefs().get(key, null);
298
        boolean usingOldKey = false;
302
        boolean usingOldKey = false;
299
        if (ownerURI == null) {
303
        if (ownerURI == null) {
(-)maven/src/org/netbeans/modules/maven/queries/MavenForBinaryQueryImpl.java (-125 / +7 lines)
Lines 44-71 Link Here
44
44
45
import java.beans.PropertyChangeEvent;
45
import java.beans.PropertyChangeEvent;
46
import java.beans.PropertyChangeListener;
46
import java.beans.PropertyChangeListener;
47
import java.io.File;
48
import java.net.URI;
49
import java.net.URL;
47
import java.net.URL;
50
import java.util.ArrayList;
48
import java.util.ArrayList;
51
import java.util.Arrays;
49
import java.util.Arrays;
52
import java.util.Collection;
53
import java.util.HashMap;
50
import java.util.HashMap;
54
import java.util.LinkedHashSet;
55
import java.util.List;
51
import java.util.List;
56
import javax.swing.event.ChangeEvent;
52
import javax.swing.event.ChangeEvent;
57
import javax.swing.event.ChangeListener;
53
import javax.swing.event.ChangeListener;
58
import org.netbeans.api.annotations.common.CheckForNull;
54
import org.netbeans.api.annotations.common.CheckForNull;
59
import org.netbeans.api.annotations.common.NullAllowed;
55
import org.netbeans.api.annotations.common.NullAllowed;
60
import org.netbeans.api.annotations.common.SuppressWarnings;
61
import org.netbeans.modules.maven.NbMavenProjectImpl;
62
import org.netbeans.modules.maven.api.NbMavenProject;
63
import org.netbeans.modules.maven.api.FileUtilities;
64
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
56
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
65
import org.netbeans.api.java.queries.SourceForBinaryQuery;
66
import org.netbeans.api.project.Project;
57
import org.netbeans.api.project.Project;
58
import org.netbeans.modules.maven.NbMavenProjectImpl;
59
import org.netbeans.modules.maven.api.NbMavenProject;
67
import org.netbeans.modules.maven.spi.queries.ForeignClassBundler;
60
import org.netbeans.modules.maven.spi.queries.ForeignClassBundler;
68
import org.netbeans.modules.maven.spi.queries.JavaLikeRootProvider;
69
import org.netbeans.spi.java.queries.JavadocForBinaryQueryImplementation;
61
import org.netbeans.spi.java.queries.JavadocForBinaryQueryImplementation;
70
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
62
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
71
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2;
63
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2;
Lines 79-91 Link Here
79
 * @author  Milos Kleint 
71
 * @author  Milos Kleint 
80
 */
72
 */
81
@ProjectServiceProvider(service={SourceForBinaryQueryImplementation.class, SourceForBinaryQueryImplementation2.class, JavadocForBinaryQueryImplementation.class}, projectType="org-netbeans-modules-maven")
73
@ProjectServiceProvider(service={SourceForBinaryQueryImplementation.class, SourceForBinaryQueryImplementation2.class, JavadocForBinaryQueryImplementation.class}, projectType="org-netbeans-modules-maven")
82
public class MavenForBinaryQueryImpl implements SourceForBinaryQueryImplementation2,
74
public class MavenForBinaryQueryImpl extends AbstractMavenForBinaryQueryImpl {
83
        JavadocForBinaryQueryImplementation {
84
    
75
    
85
    private final Project p;
76
    private final Project p;
86
    private final HashMap<String, BinResult> map;
77
    private final HashMap<String, BinResult> map;
87
78
88
    public MavenForBinaryQueryImpl(Project proj) {
79
    public MavenForBinaryQueryImpl(Project proj) {
80
        super();
89
        p = proj;
81
        p = proj;
90
        map = new HashMap<String, BinResult>();
82
        map = new HashMap<String, BinResult>();
91
        NbMavenProject.addPropertyChangeListener(proj, new PropertyChangeListener() {
83
        NbMavenProject.addPropertyChangeListener(proj, new PropertyChangeListener() {
Lines 103-121 Link Here
103
        });
95
        });
104
    }
96
    }
105
97
106
    public @Override SourceForBinaryQuery.Result findSourceRoots(URL url) {
107
        return findSourceRoots2(url);
108
    }
109
110
    public @Override SourceForBinaryQueryImplementation2.Result findSourceRoots2(URL url) {
98
    public @Override SourceForBinaryQueryImplementation2.Result findSourceRoots2(URL url) {
111
        synchronized (map) {
99
        synchronized (map) {
112
            BinResult toReturn = map.get(url.toString());
100
            BinResult toReturn = map.get(url.toString());
113
            if (toReturn != null) {
101
            if (toReturn != null) {
114
                return toReturn;
102
                return toReturn;
115
            }
103
            }
116
            if (url.getProtocol().equals("jar") && checkURL(url) != -1) { //NOI18N
117
                toReturn = new BinResult(url);
118
            }
119
            if (url.getProtocol().equals("file")) { //NOI18N
104
            if (url.getProtocol().equals("file")) { //NOI18N
120
                int result = checkURL(url);
105
                int result = checkURL(url);
121
                if (result == 1 || result == 0) {
106
                if (result == 1 || result == 0) {
Lines 153-160 Link Here
153
     * 0 - source
138
     * 0 - source
154
     * 1 - test source
139
     * 1 - test source
155
     */
140
     */
156
    @SuppressWarnings("DMI_BLOCKING_METHODS_ON_URL")
141
    protected int checkURL(URL url) {
157
    private int checkURL(URL url) {
158
        NbMavenProjectImpl project = p.getLookup().lookup(NbMavenProjectImpl.class);
142
        NbMavenProjectImpl project = p.getLookup().lookup(NbMavenProjectImpl.class);
159
        if ("file".equals(url.getProtocol())) { //NOI18N
143
        if ("file".equals(url.getProtocol())) { //NOI18N
160
            // true for directories.
144
            // true for directories.
Lines 166-276 Link Here
166
                return -1;
150
                return -1;
167
            }
151
            }
168
        }
152
        }
169
        if (Boolean.getBoolean("mevenide.projectLinksDisable")) { // #198951
170
            return -1;
153
            return -1;
171
        }
154
        }
172
        File file = FileUtil.archiveOrDirForURL(url);
173
        if (file != null) {
174
            String filepath = file.getAbsolutePath().replace('\\', '/'); //NOI18N
175
            String path = jarify(project.getArtifactRelativeRepositoryPath());
176
            int ret = path == null ? -1 : filepath.endsWith(path) ? 0 : -1;
177
            if (ret == -1) {
178
                path = jarify(project.getTestArtifactRelativeRepositoryPath());
179
                ret = path == null ? -1 : filepath.endsWith(path) ? 1 : -1;
180
            }
181
            return ret;
182
        }
183
        return -1;
184
    }
185
    static @CheckForNull String jarify(@NullAllowed String path) { // #200088
186
        return path != null ? path.replaceFirst("[.][^./]+$", ".jar") : null;
187
    }
188
    
155
    
189
    private FileObject[] getSrcRoot() {
190
        NbMavenProjectImpl project = p.getLookup().lookup(NbMavenProjectImpl.class);
191
        Collection<FileObject> toReturn = new LinkedHashSet<FileObject>();
192
        for (String item : project.getOriginalMavenProject().getCompileSourceRoots()) {
193
            FileObject fo = FileUtilities.convertStringToFileObject(item);
194
            if (fo != null) {
195
                toReturn.add(fo);
196
            }
197
        }
198
        for (URI genRoot : project.getGeneratedSourceRoots(false)) {
199
            FileObject fo = FileUtilities.convertURItoFileObject(genRoot);
200
            if (fo != null) {
201
                toReturn.add(fo);
202
            }
203
        }
204
        for (JavaLikeRootProvider rp : project.getLookup().lookupAll(JavaLikeRootProvider.class)) {
205
            FileObject fo = project.getProjectDirectory().getFileObject("src/main/" + rp.kind());
206
            if (fo != null) {
207
                toReturn.add(fo);
208
            }
209
        }
210
211
        URI[] res = project.getResources(false);
212
        for (int i = 0; i < res.length; i++) {
213
            FileObject fo = FileUtilities.convertURItoFileObject(res[i]);
214
            if (fo != null) {
215
                boolean ok = true;
216
                //#166655 resource root cannot contain the real java/xxx roots
217
                for (FileObject form : toReturn) {
218
                    if (FileUtil.isParentOf(fo, form)) {
219
                        ok = false;
220
                        break;
221
                    }
222
                }
223
                if (ok) {
224
                    toReturn.add(fo);
225
                }
226
            }
227
        }
228
        return toReturn.toArray(new FileObject[toReturn.size()]);
229
    }
230
    
231
    private FileObject[] getTestSrcRoot() {
232
        NbMavenProjectImpl project = p.getLookup().lookup(NbMavenProjectImpl.class);
233
        Collection<FileObject> toReturn = new LinkedHashSet<FileObject>();
234
        for (String item : project.getOriginalMavenProject().getTestCompileSourceRoots()) {
235
            FileObject fo = FileUtilities.convertStringToFileObject(item);
236
            if (fo != null) {
237
                toReturn.add(fo);
238
            }
239
        }
240
        for (URI genRoot : project.getGeneratedSourceRoots(true)) {
241
            FileObject fo = FileUtilities.convertURItoFileObject(genRoot);
242
            if (fo != null) {
243
                toReturn.add(fo);
244
            }
245
        }
246
        for (JavaLikeRootProvider rp : project.getLookup().lookupAll(JavaLikeRootProvider.class)) {
247
            FileObject fo = project.getProjectDirectory().getFileObject("src/test/" + rp.kind());
248
            if (fo != null) {
249
                toReturn.add(fo);
250
            }
251
        }
252
253
        URI[] res = project.getResources(true);
254
        for (int i = 0; i < res.length; i++) {
255
            FileObject fo = FileUtilities.convertURItoFileObject(res[i]);
256
            if (fo != null) {
257
                boolean ok = true;
258
                //#166655 resource root cannot contain the real java/xxx roots
259
                for (FileObject form : toReturn) {
260
                    if (FileUtil.isParentOf(fo, form)) {
261
                        ok = false;
262
                        break;
263
                    }
264
                }
265
                if (ok) {
266
                    toReturn.add(fo);
267
                }
268
            }
269
        }
270
        return toReturn.toArray(new FileObject[toReturn.size()]);
271
    }
272
    
273
    
274
    private URL[] getJavadocRoot() {
156
    private URL[] getJavadocRoot() {
275
        //TODO shall we delegate to "possibly" generated javadoc in project or in site?
157
        //TODO shall we delegate to "possibly" generated javadoc in project or in site?
276
        return new URL[0];
158
        return new URL[0];
Lines 291-299 Link Here
291
        public @Override FileObject[] getRoots() {
173
        public @Override FileObject[] getRoots() {
292
            int xxx = checkURL(url);
174
            int xxx = checkURL(url);
293
            if (xxx == 0) {
175
            if (xxx == 0) {
294
                results = getSrcRoot();
176
                results = getProjectSrcRoots(p);
295
            } else if (xxx == 1) {
177
            } else if (xxx == 1) {
296
                results = getTestSrcRoot();
178
                results = getProjectTestSrcRoots(p);
297
            } else {
179
            } else {
298
                results = new FileObject[0];
180
                results = new FileObject[0];
299
            }
181
            }
(-)maven/src/org/netbeans/modules/maven/queries/RepositoryJavadocForBinaryQueryImpl.java (-219 lines)
Lines 1-219 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 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 2008 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.maven.queries;
44
45
import java.io.File;
46
import java.io.IOException;
47
import java.net.MalformedURLException;
48
import java.net.URL;
49
import java.util.Date;
50
import java.util.logging.Level;
51
import java.util.logging.Logger;
52
import javax.swing.event.ChangeListener;
53
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
54
import org.netbeans.spi.java.project.support.JavadocAndSourceRootDetection;
55
import org.netbeans.spi.java.queries.JavadocForBinaryQueryImplementation;
56
import org.openide.ErrorManager;
57
import org.openide.filesystems.FileObject;
58
import org.openide.filesystems.FileUtil;
59
import org.openide.filesystems.URLMapper;
60
import org.openide.util.Exceptions;
61
import org.openide.modules.InstalledFileLocator;
62
import org.openide.util.lookup.ServiceProvider;
63
64
/**
65
 *
66
 * JavadocForBinaryQueryImplementation implementation
67
 * for items in the maven repository. It checks the artifact and
68
 * looks for the same artifact but of type "javadoc.jar" or "javadoc"
69
 * @author  Milos Kleint
70
 */
71
@ServiceProvider(service=JavadocForBinaryQueryImplementation.class, position=999)
72
public class RepositoryJavadocForBinaryQueryImpl implements JavadocForBinaryQueryImplementation {
73
    
74
    /**
75
     * Find any Javadoc corresponding to the given classpath root containing
76
     * Java classes.
77
     * <p>
78
     * Any absolute URL may be used but typically it will use the <code>file</code>
79
     * protocol for directory entries and <code>jar</code> protocol for JAR entries
80
     * (e.g. <samp>jar:file:/tmp/foo.jar!/</samp>).
81
     * </p>
82
     * @param binaryRoot the class path root of Java class files
83
     * @return a result object encapsulating the roots and permitting changes to
84
     *         be listened to, or null if the binary root is not recognized
85
     */
86
    @Override public JavadocForBinaryQuery.Result findJavadoc(URL url) {
87
        File stored = SourceJavadocByHash.find(url, true);
88
        if (stored != null) {
89
            return new DocResult(stored);
90
        }
91
       URL binRoot = url;
92
        if ("jar".equals(url.getProtocol())) { //NOI18N
93
            binRoot = FileUtil.getArchiveFile(url);
94
        } else {
95
            // null for directories.
96
            return null;
97
        }
98
        //hack for javaee6 jar docs which we ship with netbeans and which are not in any maven repository
99
        if (binRoot.getPath().endsWith("/javax/javaee-api/6.0/javaee-api-6.0.jar")
100
         || binRoot.getPath().endsWith("/javax/javaee-web-api/6.0/javaee-web-api-6.0.jar")) { //NOI18N
101
            return new Javaee6Result();
102
        }
103
        FileObject jarFO = URLMapper.findFileObject(binRoot);
104
        if (jarFO != null) {
105
            File jarFile = FileUtil.toFile(jarFO);
106
            if (jarFile != null) {
107
//                String name = jarFile.getName();
108
                File parent = jarFile.getParentFile();
109
                if (parent != null) {
110
                    File parentParent = parent.getParentFile();
111
                    if (parentParent != null) {
112
                        // each repository artifact should have this structure
113
                        String artifact = parentParent.getName();
114
                        String version = parent.getName();
115
                        File javadoc = new File(parent, artifact + "-" + version + "-javadoc.jar"); //NOI18N
116
                        if (javadoc.exists() || 
117
                           (jarFile.getName().startsWith(artifact) && jarFile.getName().contains(version))) { //#121657
118
                            return new DocResult(javadoc);
119
                        }
120
                    }
121
                }
122
            }
123
        }
124
        return null;
125
        
126
    }
127
    
128
    private static class DocResult implements JavadocForBinaryQuery.Result  {
129
        private static final String ATTR_PATH = "lastRootCheckPath"; //NOI18N
130
        private static final String ATTR_STAMP = "lastRootCheckStamp"; //NOI18N
131
        private File file;
132
133
        DocResult(File javadoc) {
134
            file = javadoc;
135
        }
136
137
        @Override public void addChangeListener(ChangeListener changeListener) {}
138
        
139
        @Override public void removeChangeListener(ChangeListener changeListener) {}
140
        
141
        @Override public URL[] getRoots() {
142
            try {
143
                if (file.exists()) {
144
                    FileObject fo = FileUtil.toFileObject(file);
145
                    if (!FileUtil.isArchiveFile(fo)) {
146
                        //#124175  ignore any jar files that are not jar files (like when downloaded file is actually an error html page).
147
                        Logger.getLogger(RepositoryJavadocForBinaryQueryImpl.class.getName()).log(Level.INFO, "javadoc in repository is not really a JAR: {0}", file);
148
                        return new URL[0];
149
                    }
150
                    //try detecting the source path root, in case the source jar has the sources not in root.
151
                    Date date = (Date) fo.getAttribute(ATTR_STAMP);
152
                    String path = (String) fo.getAttribute(ATTR_PATH);
153
                    if (date == null || fo.lastModified().after(date)) {
154
                        path = checkPath(FileUtil.getArchiveRoot(fo), fo);
155
                    }
156
                    
157
                    URL[] url;
158
                    if (path != null) {
159
                        url = new URL[1];
160
                        URL root = FileUtil.getArchiveRoot(file.toURI().toURL());
161
                        if (!path.endsWith("/")) { //NOI18N
162
                            path = path + "/"; //NOI18N
163
                        }
164
                        url[0] = new URL(root, path);
165
                    } else {
166
                         url = new URL[1];
167
                        url[0] = FileUtil.getArchiveRoot(file.toURI().toURL());
168
                    }
169
                    return url;
170
                }
171
            } catch (MalformedURLException exc) {
172
                ErrorManager.getDefault().notify(exc);
173
            }
174
            return new URL[0];
175
        }
176
177
        private String checkPath(FileObject jarRoot, FileObject fo) {
178
            String toRet = null;
179
            FileObject root = JavadocAndSourceRootDetection.findJavadocRoot(jarRoot);
180
            try {
181
                if (root != null && !root.equals(jarRoot)) {
182
                    toRet = FileUtil.getRelativePath(jarRoot, root);
183
                    fo.setAttribute(ATTR_PATH, toRet);
184
                }
185
                fo.setAttribute(ATTR_STAMP, new Date());
186
            } catch (IOException ex) {
187
                Exceptions.printStackTrace(ex);
188
            }
189
            return toRet;
190
        }
191
192
        
193
    }
194
195
    private static class Javaee6Result implements JavadocForBinaryQuery.Result {
196
197
        Javaee6Result() {}
198
199
        @Override public void addChangeListener(ChangeListener changeListener) {}
200
201
        @Override public void removeChangeListener(ChangeListener changeListener) {}
202
203
        @Override public URL[] getRoots() {
204
                try {
205
                    File j2eeDoc = InstalledFileLocator.getDefault().locate("docs/javaee6-doc-api.zip", "org.netbeans.modules.j2ee.platform", false); // NOI18N
206
                    if (j2eeDoc != null) {
207
                        URL url = FileUtil.getArchiveRoot(j2eeDoc.toURI().toURL());
208
                        url = new URL(url + "docs/api/"); //NOI18N
209
                        return new URL[]{url};
210
                    }
211
                } catch (MalformedURLException ex) {
212
                    Exceptions.printStackTrace(ex);
213
                }
214
                return new URL[0];
215
        }
216
217
    }
218
219
}
(-)maven/src/org/netbeans/modules/maven/queries/RepositorySourceForBinaryQueryImpl.java (-28 / +460 lines)
Lines 42-60 Link Here
42
42
43
package org.netbeans.modules.maven.queries;
43
package org.netbeans.modules.maven.queries;
44
44
45
import java.beans.PropertyChangeEvent;
46
import java.beans.PropertyChangeListener;
45
import java.io.File;
47
import java.io.File;
46
import java.io.IOException;
48
import java.io.IOException;
49
import java.lang.ref.WeakReference;
50
import java.net.MalformedURLException;
51
import java.net.URI;
47
import java.net.URL;
52
import java.net.URL;
53
import java.util.Arrays;
54
import java.util.Collections;
48
import java.util.Date;
55
import java.util.Date;
56
import java.util.HashMap;
57
import java.util.Map;
58
import java.util.logging.Level;
59
import java.util.logging.Logger;
60
import java.util.prefs.PreferenceChangeEvent;
61
import java.util.prefs.PreferenceChangeListener;
49
import javax.swing.event.ChangeListener;
62
import javax.swing.event.ChangeListener;
50
import org.netbeans.api.java.queries.SourceForBinaryQuery;
63
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
64
import org.netbeans.api.project.Project;
65
import org.netbeans.modules.maven.api.NbMavenProject;
66
import org.netbeans.modules.maven.embedder.EmbedderFactory;
67
import org.netbeans.modules.maven.spi.queries.ForeignClassBundler;
51
import org.netbeans.spi.java.project.support.JavadocAndSourceRootDetection;
68
import org.netbeans.spi.java.project.support.JavadocAndSourceRootDetection;
69
import org.netbeans.spi.java.queries.JavadocForBinaryQueryImplementation;
52
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
70
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
71
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2;
72
import org.openide.ErrorManager;
73
import org.openide.filesystems.FileChangeAdapter;
74
import org.openide.filesystems.FileChangeListener;
75
import org.openide.filesystems.FileEvent;
53
import org.openide.filesystems.FileObject;
76
import org.openide.filesystems.FileObject;
54
import org.openide.filesystems.FileUtil;
77
import org.openide.filesystems.FileUtil;
55
import org.openide.filesystems.URLMapper;
78
import org.openide.modules.InstalledFileLocator;
79
import org.openide.util.ChangeSupport;
56
import org.openide.util.Exceptions;
80
import org.openide.util.Exceptions;
81
import org.openide.util.RequestProcessor;
82
import org.openide.util.WeakListeners;
57
import org.openide.util.lookup.ServiceProvider;
83
import org.openide.util.lookup.ServiceProvider;
84
import org.openide.util.lookup.ServiceProviders;
58
85
59
/**
86
/**
60
 *
87
 *
Lines 64-87 Link Here
64
 * 
91
 * 
65
 * @author  Milos Kleint
92
 * @author  Milos Kleint
66
 */
93
 */
67
@ServiceProvider(service=SourceForBinaryQueryImplementation.class, position=999)
94
@ServiceProviders({
68
public class RepositorySourceForBinaryQueryImpl implements SourceForBinaryQueryImplementation {
95
    @ServiceProvider(service=SourceForBinaryQueryImplementation.class, position=68),
96
    @ServiceProvider(service=SourceForBinaryQueryImplementation2.class, position=68),
97
    @ServiceProvider(service=JavadocForBinaryQueryImplementation.class, position=68)
98
})
99
public class RepositorySourceForBinaryQueryImpl extends AbstractMavenForBinaryQueryImpl {
69
    
100
    
70
    @Override public SourceForBinaryQuery.Result findSourceRoots(URL url) {
101
71
        File stored = SourceJavadocByHash.find(url, false);
102
    private final Map<URL, WeakReference<SrcResult>> srcCache = Collections.synchronizedMap(new HashMap<URL, WeakReference<SrcResult>>());
72
        if (stored != null) {
103
    private final Map<URL, WeakReference<JavadocResult>> javadocCache = Collections.synchronizedMap(new HashMap<URL, WeakReference<JavadocResult>>());
73
            return new SrcResult(stored);
104
    
105
    
106
    private static final RequestProcessor RP = new RequestProcessor("Maven Repository SFBQ result change");
107
    
108
    @Override
109
    public synchronized Result findSourceRoots2(URL url) {
110
        if (!"jar".equals(url.getProtocol())) { //NOI18N
111
            // null for directories.
112
            return null;
74
        }
113
        }
75
        URL binRoot = url;
114
        
115
        WeakReference<SrcResult> cached = srcCache.get(url);
116
        if (cached != null) {
117
            SrcResult result = cached.get();
118
            if (result != null) {
119
                return result;
120
            }
121
        }
122
        
123
        File jarFile = FileUtil.archiveOrDirForURL(url);
124
        if (jarFile != null) {
125
//                String name = jarFile.getName();
126
            File parent = jarFile.getParentFile();
127
            if (parent != null) {
128
                File parentParent = parent.getParentFile();
129
                if (parentParent != null) {
130
                    // each repository artifact should have this structure
131
                    String artifact = parentParent.getName();
132
                    String version = parent.getName();
133
//                        File pom = new File(parent, artifact + "-" + version + ".pom");
134
//                        // maybe this condition is already overkill..
135
//                        if (pom.exists()) {
136
                    File srcs = new File(parent, artifact + "-" + version + "-sources.jar"); //NOI18N
137
                    if (jarFile.getName().startsWith(artifact + "-" + version)) { //one last perf check before calling the embedder
138
                        URI localRepo = EmbedderFactory.getProjectEmbedder().getLocalRepositoryFile().toURI();
139
                        URI rel = localRepo.relativize(parentParent.getParentFile().toURI());
140
                        if (!rel.isAbsolute()) {
141
                            String groupId = rel.getPath();
142
                            if (groupId != null && !groupId.equals("")) {
143
                                groupId = groupId.replace("/", ".");
144
                                if (groupId.endsWith(".")) {
145
                                    groupId = groupId.substring(0, groupId.length() - 1);
146
                                }
147
                                SrcResult result = new SrcResult(groupId, artifact, version, FileUtil.getArchiveFile(url), srcs);
148
                                srcCache.put(url, new WeakReference<SrcResult>(result));
149
                                return result;
150
                            }
151
                        }
152
153
                    }
154
//                        }
155
                }
156
            }
157
        }
158
        return null;
159
                
160
    }
161
    
162
    @Override
163
    public JavadocForBinaryQuery.Result findJavadoc(URL url) {
164
        URL binRoot;
76
        if ("jar".equals(url.getProtocol())) { //NOI18N
165
        if ("jar".equals(url.getProtocol())) { //NOI18N
77
            binRoot = FileUtil.getArchiveFile(url);
166
            binRoot = FileUtil.getArchiveFile(url);
78
        } else {
167
        } else {
79
            // null for directories.
168
            // null for directories.
80
            return null;
169
            return null;
81
        }
170
        }
82
        FileObject jarFO = URLMapper.findFileObject(binRoot);
171
        
83
        if (jarFO != null) {
172
        //hack for javaee6 jar docs which we ship with netbeans and which are not in any maven repository
84
            File jarFile = FileUtil.toFile(jarFO);
173
        if (binRoot.getPath().endsWith("/javax/javaee-api/6.0/javaee-api-6.0.jar")
174
         || binRoot.getPath().endsWith("/javax/javaee-web-api/6.0/javaee-web-api-6.0.jar")) { //NOI18N
175
            return new Javaee6Result();
176
        }
177
        
178
        WeakReference<JavadocResult> cached = javadocCache.get(url);
179
        if (cached != null) {
180
            JavadocResult result = cached.get();
181
            if (result != null) {
182
                return result;
183
            }
184
        }
185
        
186
        
187
        File jarFile = FileUtil.archiveOrDirForURL(url);
85
            if (jarFile != null) {
188
            if (jarFile != null) {
86
//                String name = jarFile.getName();
189
//                String name = jarFile.getName();
87
                File parent = jarFile.getParentFile();
190
                File parent = jarFile.getParentFile();
Lines 94-128 Link Here
94
//                        File pom = new File(parent, artifact + "-" + version + ".pom");
197
//                        File pom = new File(parent, artifact + "-" + version + ".pom");
95
//                        // maybe this condition is already overkill..
198
//                        // maybe this condition is already overkill..
96
//                        if (pom.exists()) {
199
//                        if (pom.exists()) {
97
                            File srcs = new File(parent, artifact + "-" + version + "-sources.jar"); //NOI18N
200
                    File javadoc = new File(parent, artifact + "-" + version + "-javadoc.jar"); //NOI18N
98
                            if (srcs.exists()) {
201
                    if (jarFile.getName().startsWith(artifact + "-" + version)) { //one last perf check before calling the embedder
99
                                return new SrcResult(srcs);
202
                        URI localRepo = EmbedderFactory.getProjectEmbedder().getLocalRepositoryFile().toURI();
203
                        URI rel = localRepo.relativize(parentParent.getParentFile().toURI());
204
                        if (!rel.isAbsolute()) {
205
                            String groupId = rel.getPath();
206
                            if (groupId != null && !groupId.equals("")) {
207
                                groupId = groupId.replace("/", ".");
208
                                if (groupId.endsWith(".")) {
209
                                    groupId = groupId.substring(0, groupId.length() - 1);
100
                            }
210
                            }
101
//                        }
211
                                JavadocResult result = new JavadocResult(groupId, artifact, version, binRoot, javadoc);
212
                                javadocCache.put(url, new WeakReference<JavadocResult>(result));
213
                                return result;
102
                    }
214
                    }
103
                }
215
                }
216
104
            }
217
            }
218
//                        }
105
        }
219
        }
220
            }
221
        }
106
        return null;
222
        return null;
107
                
108
    }
223
    }
109
    
224
    
110
    private static class SrcResult implements SourceForBinaryQuery.Result  {
225
    private static class SrcResult implements SourceForBinaryQueryImplementation2.Result  {
111
        private static final String ATTR_PATH = "lastRootCheckPath"; //NOI18N
226
        private static final String ATTR_PATH = "lastRootCheckPath"; //NOI18N
112
        private static final String ATTR_STAMP = "lastRootCheckStamp"; //NOI18N
227
        private static final String ATTR_STAMP = "lastRootCheckStamp"; //NOI18N
113
        private File file;
228
        private final File sourceJarFile;
229
        private final ChangeSupport support;
230
        private final PreferenceChangeListener prefListener;
231
        private final PropertyChangeListener projectListener;
232
        private final FileChangeListener sourceJarChangeListener;
233
        private final String groupId;
234
        private final String artifactId;
235
        private final String version;
236
        private final String gav;
237
        private final URL binary;
114
        
238
        
115
        SrcResult(File src) {
239
        private Project currentProject;
116
            file = src;
240
        private FileObject[] cached;
241
242
        
243
        SrcResult(String groupId, String artifactId, String version, URL binary, File sourceJar) {
244
            sourceJarFile = sourceJar;
245
            this.groupId = groupId;
246
            this.artifactId = artifactId;
247
            this.version = version;
248
            this.binary = binary;
249
            this.gav = MavenFileOwnerQueryImpl.cacheKey(groupId, artifactId, version);
250
            
251
            support = new ChangeSupport(this);
252
            prefListener = new PreferenceChangeListener() {
253
                @Override
254
                public void preferenceChange(PreferenceChangeEvent evt) {
255
                    if (gav.equals(evt.getKey())) {
256
                        //external root in local repository changed..
257
                        checkChanges();
117
        }
258
        }
259
                }
260
            };
261
            projectListener = new PropertyChangeListener() {
262
                public @Override
263
                void propertyChange(PropertyChangeEvent event) {
264
                    if (NbMavenProject.PROP_PROJECT.equals(event.getPropertyName())) {
265
                        //project could have changed source roots..
266
                        checkChanges();
267
                    }
268
                }
269
            };
270
            sourceJarChangeListener = new FileChangeAdapter(){
271
                @Override
272
                public void fileDataCreated(FileEvent fe) {
273
                    //source jar was created..
274
                    checkChanges();
275
                }
118
276
119
        @Override public void addChangeListener(ChangeListener changeListener) {}
277
            };
278
            MavenFileOwnerQueryImpl.prefs().addPreferenceChangeListener(
279
                    WeakListeners.create(PreferenceChangeListener.class, prefListener, MavenFileOwnerQueryImpl.prefs()));
120
        
280
        
121
        @Override public void removeChangeListener(ChangeListener changeListener) {}
281
            FileUtil.addFileChangeListener(FileUtil.weakFileChangeListener(sourceJarChangeListener, sourceJar));
282
        }
122
        
283
        
123
        @Override public FileObject[] getRoots() {
284
        private void checkChanges() {
124
            if (file.exists()) {
285
            if (!Arrays.equals(getCached(), getRoots())) {
125
                FileObject fo = FileUtil.toFileObject(file);
286
                support.fireChange();
287
            }
288
        }
289
        /**
290
         * use MFOQI to determine what is the current project owning our coordinates in local repository.
291
         */
292
        private void checkCurrentProject() {
293
            Project owner = MavenFileOwnerQueryImpl.getInstance().getOwner(groupId, artifactId, version);
294
            if (owner != null && owner.getLookup().lookup(NbMavenProject.class) == null) {
295
                owner = null;
296
            }
297
            //XXX TODO should we be attaching a weak listener here?
298
            if (currentProject != null && !currentProject.equals(owner)) {
299
                currentProject.getLookup().lookup(NbMavenProject.class).removePropertyChangeListener(projectListener);
300
            }
301
            if (owner != null && !owner.equals(currentProject)) {
302
                owner.getLookup().lookup(NbMavenProject.class).addPropertyChangeListener(projectListener);
303
            }
304
            currentProject = owner;
305
        }     
306
307
        @Override 
308
        public void addChangeListener(ChangeListener changeListener) {
309
            support.addChangeListener(changeListener);
310
        }
311
        
312
        @Override 
313
        public void removeChangeListener(ChangeListener changeListener) {
314
            support.removeChangeListener(changeListener);
315
        }
316
        
317
        @Override 
318
        public FileObject[] getRoots() {
319
            FileObject[] toRet;
320
            checkCurrentProject();
321
            Project prj = currentProject;
322
            if (prj != null) {
323
                toRet = getProjectSrcRoots(prj);
324
            } else {
325
                File f = SourceJavadocByHash.find(binary, false);
326
                if (f != null && f.exists()) {
327
                    toRet = getSourceJarRoot(f);
328
                }
329
                else if (sourceJarFile.exists()) {
330
                    toRet = getSourceJarRoot(sourceJarFile);
331
                } else {
332
                    toRet = new FileObject[0];
333
                }
334
            }
335
            if (!Arrays.equals(cached, toRet)) {
336
                //how to figure otherwise that something changed, possibly multiple people hold the result instance
337
                // and one asks the roots, later we get event from outside, but then the cached value already updated..
338
                RP.post(new Runnable() {
339
                    @Override
340
                    public void run() {
341
                        support.fireChange();
342
                    }
343
                });
344
            }
345
            cached = toRet;
346
            return toRet;
347
        }
348
        
349
        public FileObject[] getCached() {
350
            return cached;
351
        }
352
353
        private String checkPath(FileObject jarRoot, FileObject fo) {
354
            String toRet = null;
355
            FileObject root = JavadocAndSourceRootDetection.findSourceRoot(jarRoot);
356
            try {
357
                if (root != null && !root.equals(jarRoot)) {
358
                    toRet = FileUtil.getRelativePath(jarRoot, root);
359
                    fo.setAttribute(ATTR_PATH, toRet);
360
                }
361
                fo.setAttribute(ATTR_STAMP, new Date());
362
            } catch (IOException ex) {
363
                Exceptions.printStackTrace(ex);
364
            }
365
            return toRet;
366
        }
367
368
        private FileObject[] getSourceJarRoot(File sourceJar) {
369
            FileObject fo = FileUtil.toFileObject(sourceJar);
126
                FileObject jarRoot = FileUtil.getArchiveRoot(fo);
370
                FileObject jarRoot = FileUtil.getArchiveRoot(fo);
127
                if (jarRoot != null) { //#139894 it seems that sometimes it can return null.
371
                if (jarRoot != null) { //#139894 it seems that sometimes it can return null.
128
                                  // I suppose it's in the case when the jar/zip file in repository exists
372
                                  // I suppose it's in the case when the jar/zip file in repository exists
Lines 145-157 Link Here
145
                    }
389
                    }
146
                    return fos;
390
                    return fos;
147
                }
391
                }
148
            }
149
            return new FileObject[0];
392
            return new FileObject[0];
150
        }
393
        }
151
394
395
        @Override
396
        public boolean preferSources() {
397
            Project prj = currentProject;
398
            if (prj != null) {
399
                //TODO is project broken or not, handle accordingly..
400
                return prj.getLookup().lookup(ForeignClassBundler.class).preferSources();
401
            }
402
            return false;
403
        }
404
        
405
    }  
406
    
407
    private static class JavadocResult implements JavadocForBinaryQuery.Result {
408
        private final File sourceJarFile;
409
        private final String groupId;
410
        private final String artifactId;
411
        private final String version;
412
        private final URL binary;
413
        private final String gav;
414
        private final ChangeSupport support;
415
        private final PreferenceChangeListener prefListener;
416
        private final PropertyChangeListener projectListener;
417
        private final FileChangeAdapter javadocJarChangeListener;
418
        private Project currentProject;
419
        private URL[] cached;
420
        private static final String ATTR_PATH = "lastRootCheckPath"; //NOI18N
421
        private static final String ATTR_STAMP = "lastRootCheckStamp"; //NOI18N
422
        
423
424
        
425
        JavadocResult(String groupId, String artifactId, String version, URL binary, File javadocJar) {
426
            sourceJarFile = javadocJar;
427
            this.groupId = groupId;
428
            this.artifactId = artifactId;
429
            this.version = version;
430
            this.binary = binary;
431
            this.gav = MavenFileOwnerQueryImpl.cacheKey(groupId, artifactId, version);
432
            
433
            support = new ChangeSupport(this);
434
            prefListener = new PreferenceChangeListener() {
435
                @Override
436
                public void preferenceChange(PreferenceChangeEvent evt) {
437
                    if (gav.equals(evt.getKey())) {
438
                        //external root in local repository changed..
439
                        checkCurrentProject();
440
                        checkChanges();
441
                   }
442
                }
443
            };
444
            projectListener = new PropertyChangeListener() {
445
                public @Override
446
                void propertyChange(PropertyChangeEvent event) {
447
                    if (NbMavenProject.PROP_PROJECT.equals(event.getPropertyName())) {
448
                        //project could have changed coordinates..
449
                        checkCurrentProject();
450
                        checkChanges();
451
                    }
452
                }
453
            };
454
            javadocJarChangeListener = new FileChangeAdapter(){
455
                @Override
456
                public void fileDataCreated(FileEvent fe) {
457
                    //source jar was created..
458
                    checkChanges();
459
                }
460
461
            };
462
            MavenFileOwnerQueryImpl.prefs().addPreferenceChangeListener(
463
                    WeakListeners.create(PreferenceChangeListener.class, prefListener, MavenFileOwnerQueryImpl.prefs()));
464
        
465
            FileUtil.addFileChangeListener(javadocJarChangeListener, javadocJar);
466
        }        
467
        @Override
468
        public URL[] getRoots() {
469
            URL[] toRet;
470
            Project prj = currentProject;
471
            if (prj != null) {
472
                toRet = new URL[0];
473
            } else {
474
                File f = SourceJavadocByHash.find(binary, true);
475
                if (f != null && f.exists()) {
476
                    toRet = getJavadocJarRoot(f);
477
                }
478
                else if (sourceJarFile.exists()) {
479
                    toRet = getJavadocJarRoot(sourceJarFile);
480
                } else {
481
                    toRet = new URL[0];
482
                }
483
            }
484
            cached = toRet;
485
            return toRet;
486
        }
487
        
488
        public URL[] getCached() {
489
            return cached;
490
        }
491
492
        @Override
493
        public void addChangeListener(ChangeListener l) {
494
            support.addChangeListener(l);
495
        }
496
497
        @Override
498
        public void removeChangeListener(ChangeListener l) {
499
            support.removeChangeListener(l);
500
        }
501
        
502
        private void checkChanges() {
503
            if (!Arrays.equals(getCached(), getRoots())) {
504
                support.fireChange();
505
            }
506
        }
507
        /**
508
         * use MFOQI to determine what is the current project owning our coordinates in local repository.
509
         */
510
        private void checkCurrentProject() {
511
            Project owner = MavenFileOwnerQueryImpl.getInstance().getOwner(groupId, artifactId, version);
512
            if (owner != null && owner.getLookup().lookup(NbMavenProject.class) == null) {
513
                owner = null;
514
            }
515
            if (currentProject != null && !currentProject.equals(owner)) {
516
                currentProject.getLookup().lookup(NbMavenProject.class).removePropertyChangeListener(projectListener);
517
            }
518
            if (owner != null && !owner.equals(currentProject)) {
519
                owner.getLookup().lookup(NbMavenProject.class).addPropertyChangeListener(projectListener);
520
            }
521
            currentProject = owner;
522
        }         
523
524
        private URL[] getJavadocJarRoot(File file) {
525
            try {
526
                if (file.exists()) {
527
                    FileObject fo = FileUtil.toFileObject(file);
528
                    if (!FileUtil.isArchiveFile(fo)) {
529
                        //#124175  ignore any jar files that are not jar files (like when downloaded file is actually an error html page).
530
                        Logger.getLogger(RepositorySourceForBinaryQueryImpl.class.getName()).log(Level.INFO, "javadoc in repository is not really a JAR: {0}", file);
531
                        return new URL[0];
532
                    }
533
                    //try detecting the source path root, in case the source jar has the sources not in root.
534
                    Date date = (Date) fo.getAttribute(ATTR_STAMP);
535
                    String path = (String) fo.getAttribute(ATTR_PATH);
536
                    if (date == null || fo.lastModified().after(date)) {
537
                        path = checkPath(FileUtil.getArchiveRoot(fo), fo);
538
                    }
539
                    
540
                    URL[] url;
541
                    if (path != null) {
542
                        url = new URL[1];
543
                        URL root = FileUtil.getArchiveRoot(file.toURI().toURL());
544
                        if (!path.endsWith("/")) { //NOI18N
545
                            path = path + "/"; //NOI18N
546
                        }
547
                        url[0] = new URL(root, path);
548
                    } else {
549
                         url = new URL[1];
550
                        url[0] = FileUtil.getArchiveRoot(file.toURI().toURL());
551
                    }
552
                    return url;
553
                }
554
            } catch (MalformedURLException exc) {
555
                ErrorManager.getDefault().notify(exc);
556
            }
557
            return new URL[0];
558
        }
559
152
        private String checkPath(FileObject jarRoot, FileObject fo) {
560
        private String checkPath(FileObject jarRoot, FileObject fo) {
153
            String toRet = null;
561
            String toRet = null;
154
            FileObject root = JavadocAndSourceRootDetection.findSourceRoot(jarRoot);
562
            FileObject root = JavadocAndSourceRootDetection.findJavadocRoot(jarRoot);
155
            try {
563
            try {
156
                if (root != null && !root.equals(jarRoot)) {
564
                if (root != null && !root.equals(jarRoot)) {
157
                    toRet = FileUtil.getRelativePath(jarRoot, root);
565
                    toRet = FileUtil.getRelativePath(jarRoot, root);
Lines 166-169 Link Here
166
        
574
        
167
    }    
575
    }    
168
    
576
    
577
   private static class Javaee6Result implements JavadocForBinaryQuery.Result {
578
579
        Javaee6Result() {}
580
581
        @Override public void addChangeListener(ChangeListener changeListener) {}
582
583
        @Override public void removeChangeListener(ChangeListener changeListener) {}
584
585
        @Override public URL[] getRoots() {
586
                try {
587
                    File j2eeDoc = InstalledFileLocator.getDefault().locate("docs/javaee6-doc-api.zip", "org.netbeans.modules.j2ee.platform", false); // NOI18N
588
                    if (j2eeDoc != null) {
589
                        URL url = FileUtil.getArchiveRoot(j2eeDoc.toURI().toURL());
590
                        url = new URL(url + "docs/api/"); //NOI18N
591
                        return new URL[]{url};
169
}
592
}
593
                } catch (MalformedURLException ex) {
594
                    Exceptions.printStackTrace(ex);
595
                }
596
                return new URL[0];
597
        }
598
599
    }    
600
    
601
}
(-)maven/test/unit/src/org/netbeans/modules/maven/queries/RepositorySourceForBinaryQueryImplTest.java (+137 lines)
Line 0 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.netbeans.modules.maven.queries;
43
44
import java.io.File;
45
import java.io.IOException;
46
import java.net.URL;
47
import java.util.Arrays;
48
import org.junit.Test;
49
import static org.junit.Assert.*;
50
import org.netbeans.api.project.ProjectManager;
51
import org.netbeans.junit.NbTestCase;
52
import org.netbeans.modules.maven.NbMavenProjectImpl;
53
import org.netbeans.modules.maven.embedder.EmbedderFactory;
54
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2.Result;
55
import org.openide.filesystems.FileUtil;
56
import org.openide.util.Exceptions;
57
import org.openide.util.test.TestFileUtils;
58
59
/**
60
 *
61
 * @author mkleint
62
 */
63
public class RepositorySourceForBinaryQueryImplTest extends NbTestCase{
64
    
65
    public RepositorySourceForBinaryQueryImplTest(String name) {
66
        super(name);
67
    }
68
    
69
    /**
70
     * Test of findSourceRoots2 method, of class RepositorySourceForBinaryQueryImpl.
71
     */
72
    @Test
73
    public void testResultChanging() throws IOException {
74
        RepositorySourceForBinaryQueryImpl query = new RepositorySourceForBinaryQueryImpl();
75
        File repo = EmbedderFactory.getProjectEmbedder().getLocalRepositoryFile();
76
        File art10 = new File(repo, "nbtest/testprj/1.0/testprj-1.0.jar");
77
        org.codehaus.plexus.util.FileUtils.deleteDirectory(art10.getParentFile());
78
        URL url = FileUtil.getArchiveRoot(art10.toURI().toURL());
79
        TestFileUtils.writeZipFile(art10, "META-INF/MANIFEST.MF:Version:1.0");
80
        Result result = query.findSourceRoots2(url);
81
        assertNotNull(result);
82
        assertEquals(0, result.getRoots().length);
83
        
84
85
        // now create source jar
86
        File sourceJar = new File(this.getDataDir(), "source.jar");
87
        File repoSourceJar = new File(art10.getParentFile(), "testprj-1.0-sources.jar");
88
        org.codehaus.plexus.util.FileUtils.copyFile(sourceJar, repoSourceJar);
89
        assertEquals(1, result.getRoots().length);
90
        assertEquals(FileUtil.getArchiveRoot(FileUtil.toFileObject(repoSourceJar)), result.getRoots()[0]);
91
        
92
        
93
        
94
        //now create project
95
        File prj10 = new File(getWorkDir(), "prj10");
96
        TestFileUtils.writeFile(new File(prj10, "pom.xml"), "<project><modelVersion>4.0.0</modelVersion>"
97
                + "<groupId>nbtest</groupId><artifactId>testprj</artifactId>"
98
                + "<packaging>jar</packaging><version>1.0</version></project>");
99
        //create main source root.
100
        File prjroot = new File(new File(new File(prj10, "src"), "main"), "java");
101
        prjroot.mkdirs();
102
        
103
        NbMavenProjectImpl p10 = (NbMavenProjectImpl) ProjectManager.getDefault().findProject(FileUtil.toFileObject(prj10));
104
        assertNotNull(p10);
105
        MavenFileOwnerQueryImpl.getInstance().registerProject(p10);
106
        try {
107
            //preferences changes get fired in different thread, need to wait for it.. 
108
            Thread.sleep(2000);
109
        } catch (InterruptedException ex) {
110
            Exceptions.printStackTrace(ex);
111
        }
112
        assertEquals(1, result.getRoots().length);
113
        assertEquals(FileUtil.toFileObject(prjroot), result.getRoots()[0]);
114
        
115
        //overwrite the pom file to point to different 
116
        TestFileUtils.writeFile(new File(prj10, "pom.xml"), "<project><modelVersion>4.0.0</modelVersion>"
117
                + "<groupId>nbtest</groupId><artifactId>testprj</artifactId>"
118
                + "<packaging>jar</packaging><version>1.0</version>"
119
                + "<build><sourceDirectory>src/main2/java</sourceDirectory></build>"
120
                + "</project>");
121
        //manually reload the project, only opened projects listen on pom.xml changes.
122
        p10.fireProjectReload();
123
        
124
        
125
        System.out.println("res=" + Arrays.toString(result.getRoots()));
126
        assertEquals(0, result.getRoots().length);
127
        prjroot = new File(new File(new File(prj10, "src"), "main2"), "java");
128
        prjroot.mkdirs();
129
        
130
        assertEquals(1, result.getRoots().length);
131
        assertEquals(FileUtil.toFileObject(prjroot), result.getRoots()[0]);
132
        
133
        
134
        
135
    }
136
137
}

Return to bug 203222