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

(-)a/core.startup/nbproject/project.xml (-1 / +1 lines)
Lines 63-69 Link Here
63
                    <build-prerequisite/>
63
                    <build-prerequisite/>
64
                    <compile-dependency/>
64
                    <compile-dependency/>
65
                    <run-dependency>
65
                    <run-dependency>
66
                        <specification-version>7.57</specification-version>
66
                        <specification-version>7.59</specification-version>
67
                    </run-dependency>
67
                    </run-dependency>
68
                </dependency>
68
                </dependency>
69
                <dependency>
69
                <dependency>
(-)a/core.startup/src/org/netbeans/core/startup/NbRepository.java (-1 / +26 lines)
Lines 47-59 Link Here
47
import java.beans.PropertyVetoException;
47
import java.beans.PropertyVetoException;
48
import java.io.File;
48
import java.io.File;
49
import java.io.IOException;
49
import java.io.IOException;
50
import java.net.URL;
50
import java.util.ArrayList;
51
import java.util.ArrayList;
51
import java.util.List;
52
import java.util.List;
52
import java.util.StringTokenizer;
53
import java.util.StringTokenizer;
54
import java.util.concurrent.ExecutionException;
55
import java.util.concurrent.Future;
56
import java.util.concurrent.TimeUnit;
57
import java.util.concurrent.TimeoutException;
58
import org.netbeans.core.startup.layers.ModuleLayeredFileSystem;
53
59
54
import org.openide.filesystems.*;
60
import org.openide.filesystems.*;
55
61
56
import org.netbeans.core.startup.layers.SessionManager;
62
import org.netbeans.core.startup.layers.SessionManager;
63
import org.openide.util.Exceptions;
64
import org.openide.util.Lookup;
57
import org.openide.util.NbBundle;
65
import org.openide.util.NbBundle;
58
66
59
/** Default repository.
67
/** Default repository.
Lines 170-174 Link Here
170
    private static void doExit (int value) {
178
    private static void doExit (int value) {
171
        TopLogging.exit(value);
179
        TopLogging.exit(value);
172
    }
180
    }
173
    
181
182
    public List<URL> additionalLayers(List<URL> urls) {
183
        for (LayersProvider p : Lookup.getDefault().lookupAll(LayersProvider.class)) {
184
            List<URL> mix = new ArrayList<URL>(urls);
185
            mix.addAll(findLayers(p));
186
            urls = mix;
187
        }
188
        return urls;
189
    }
190
191
    @Override
192
    protected void refreshAdditionalLayers() {
193
        try {
194
            ModuleLayeredFileSystem.getInstallationModuleLayer().setURLs(null);
195
        } catch (Exception ex) {
196
            Exceptions.printStackTrace(ex);
197
        }
198
    }
174
}
199
}
(-)a/core.startup/src/org/netbeans/core/startup/layers/ModuleLayeredFileSystem.java (-12 / +41 lines)
Lines 54-64 Link Here
54
import java.util.jar.Manifest;
54
import java.util.jar.Manifest;
55
import java.util.logging.Level;
55
import java.util.logging.Level;
56
import java.util.logging.Logger;
56
import java.util.logging.Logger;
57
import org.netbeans.core.startup.NbRepository;
57
import org.netbeans.core.startup.StartLog;
58
import org.netbeans.core.startup.StartLog;
58
import org.openide.filesystems.FileStateInvalidException;
59
import org.openide.filesystems.FileStateInvalidException;
59
import org.openide.filesystems.FileSystem;
60
import org.openide.filesystems.FileSystem;
60
import org.openide.filesystems.FileUtil;
61
import org.openide.filesystems.FileUtil;
61
import org.openide.filesystems.MultiFileSystem;
62
import org.openide.filesystems.MultiFileSystem;
63
import org.openide.filesystems.Repository.LayersProvider;
62
import org.openide.filesystems.XMLFileSystem;
64
import org.openide.filesystems.XMLFileSystem;
63
import org.openide.modules.ModuleInfo;
65
import org.openide.modules.ModuleInfo;
64
import org.openide.util.Lookup;
66
import org.openide.util.Lookup;
Lines 78-88 Link Here
78
    
80
    
79
    static final Logger err = Logger.getLogger("org.netbeans.core.projects"); // NOI18N
81
    static final Logger err = Logger.getLogger("org.netbeans.core.projects"); // NOI18N
80
82
81
    /** lookup result we listen on */
83
    /** lookup result for registered filesystems */
82
    private static Lookup.Result<FileSystem> result = Lookup.getDefault().lookupResult(FileSystem.class);
84
    private static Lookup.Result<FileSystem> fsResult = Lookup.getDefault().lookupResult(FileSystem.class);
85
    private static Lookup.Result<LayersProvider> layerResult = Lookup.getDefault().lookupResult(LayersProvider.class);
83
86
84
    /** current list of URLs - r/o; or null if not yet set */
87
    /** current list of URLs - r/o; or null if not yet set */
85
    private List<URL> urls;
88
    private List<URL> urls;
89
    private List<URL> prevs;
86
    /** cache manager */
90
    /** cache manager */
87
    private LayerCacheManager manager;
91
    private LayerCacheManager manager;
88
    /** writable layer */
92
    /** writable layer */
Lines 130-144 Link Here
130
        
134
        
131
        urls = null;
135
        urls = null;
132
136
133
        result.addLookupListener(this);
137
        fsResult.addLookupListener(this);
134
        result.allItems();
138
        layerResult.addLookupListener(this);
135
    }
139
    }
136
    
140
    
137
    private static FileSystem[] appendLayers(FileSystem fs1, boolean addLookupBefore, FileSystem[] fs2s, FileSystem fs3, boolean addClasspathLayers) {
141
    private static FileSystem[] appendLayers(FileSystem fs1, boolean addLookupBefore, FileSystem[] fs2s, FileSystem fs3, boolean addClasspathLayers) {
138
        List<FileSystem> l = new ArrayList<FileSystem>(fs2s.length + 2);
142
        List<FileSystem> l = new ArrayList<FileSystem>(fs2s.length + 2);
139
        l.add(fs1);
143
        l.add(fs1);
140
        if (addLookupBefore) {
144
        if (addLookupBefore) {
141
            for (FileSystem f : result.allInstances()) {
145
            for (FileSystem f : fsResult.allInstances()) {
142
                if (Boolean.TRUE.equals(f.getRoot().getAttribute("fallback"))) { // NOI18N
146
                if (Boolean.TRUE.equals(f.getRoot().getAttribute("fallback"))) { // NOI18N
143
                    continue;
147
                    continue;
144
                }
148
                }
Lines 163-169 Link Here
163
            }
167
            }
164
        }
168
        }
165
        if (!addLookupBefore) {
169
        if (!addLookupBefore) {
166
            for (FileSystem f : result.allInstances()) {
170
            for (FileSystem f : fsResult.allInstances()) {
167
                if (Boolean.TRUE.equals(f.getRoot().getAttribute("fallback"))) { // NOI18N
171
                if (Boolean.TRUE.equals(f.getRoot().getAttribute("fallback"))) { // NOI18N
168
                    l.add(f);
172
                    l.add(f);
169
                }
173
                }
Lines 222-234 Link Here
222
    /** Change the list of module layers URLs.
226
    /** Change the list of module layers URLs.
223
     * @param urls the urls describing module layers to use. List<URL>
227
     * @param urls the urls describing module layers to use. List<URL>
224
     */
228
     */
225
    public void setURLs (final List<URL> urls) throws Exception {
229
    public void setURLs (List<URL> urls) throws Exception {
230
        if (urls == null) {
231
            urls = this.prevs;
232
        }
233
        if (urls == null) {
234
            return;
235
        }
226
        if (urls.contains(null)) {
236
        if (urls.contains(null)) {
227
            throw new NullPointerException("urls=" + urls);
237
            throw new NullPointerException("urls=" + urls);
228
        } // NOI18N
238
        } // NOI18N
229
        if (err.isLoggable(Level.FINE)) {
239
        if (err.isLoggable(Level.FINE)) {
230
            err.log(Level.FINE, "setURLs: {0}", urls);
240
            err.log(Level.FINE, "setURLs: {0}", urls);
231
        }
241
        }
242
        List<URL> orig = urls;
243
        if (this == ModuleLayeredFileSystem.getInstallationModuleLayer()) {
244
            urls = ((NbRepository)NbRepository.getDefault()).additionalLayers(urls);
245
        }
232
        if (this.urls != null && urls.equals(this.urls)) {
246
        if (this.urls != null && urls.equals(this.urls)) {
233
            err.fine("no-op");
247
            err.fine("no-op");
234
            return;
248
            return;
Lines 248-253 Link Here
248
        }
262
        }
249
        
263
        
250
        this.urls = urls;
264
        this.urls = urls;
265
        this.prevs = orig;
251
        firePropertyChange ("layers", null, null); // NOI18N
266
        firePropertyChange ("layers", null, null); // NOI18N
252
        
267
        
253
        StartLog.logEnd("setURLs"); // NOI18N
268
        StartLog.logEnd("setURLs"); // NOI18N
Lines 261-268 Link Here
261
        }
276
        }
262
        // Add to the front: #23609.
277
        // Add to the front: #23609.
263
        ArrayList<URL> arr = new ArrayList<URL>(urls);
278
        ArrayList<URL> arr = new ArrayList<URL>(urls);
264
        if (this.urls != null) {
279
        if (this.prevs != null) {
265
            arr.addAll(this.urls);
280
            arr.addAll(this.prevs);
266
        }
281
        }
267
        setURLs(arr);
282
        setURLs(arr);
268
    }
283
    }
Lines 274-281 Link Here
274
            throw new NullPointerException("urls=" + urls);
289
            throw new NullPointerException("urls=" + urls);
275
        }
290
        }
276
        ArrayList<URL> arr = new ArrayList<URL>();
291
        ArrayList<URL> arr = new ArrayList<URL>();
277
        if (this.urls != null) {
292
        if (this.prevs != null) {
278
            arr.addAll(this.urls);
293
            arr.addAll(this.prevs);
279
        }
294
        }
280
        arr.removeAll(urls);
295
        arr.removeAll(urls);
281
        setURLs(arr);
296
        setURLs(arr);
Lines 283-289 Link Here
283
    
298
    
284
    /** Refresh layers */
299
    /** Refresh layers */
285
    @Override public void resultChanged(LookupEvent ev) {
300
    @Override public void resultChanged(LookupEvent ev) {
286
        setDelegates(appendLayers(writableLayer, addLookupBefore, otherLayers, cacheLayer, addLookupBefore));
301
        if (ev.getSource() == fsResult) {
302
            setDelegates(appendLayers(writableLayer, addLookupBefore, otherLayers, cacheLayer, addLookupBefore));
303
            return;
304
        }
305
        if (ev.getSource() == layerResult) {
306
            if (prevs != null) {
307
                try {
308
                    setURLs(prevs);
309
                } catch (Exception ex) {
310
                    err.log(Level.INFO, null, ex);
311
                }
312
            }
313
            return;
314
        }
315
        throw new IllegalStateException("Unknown source: " + ev.getSource());
287
    }
316
    }
288
    
317
    
289
    public static List<URL> collectLayers(ClassLoader loader) throws IOException {
318
    public static List<URL> collectLayers(ClassLoader loader) throws IOException {
(-)a/core.startup/test/unit/src/org/netbeans/core/startup/layers/ContentProviderTest.java (+118 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 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 2011 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.core.startup.layers;
43
44
import java.net.URL;
45
import java.util.Collection;
46
import java.util.Collections;
47
import java.util.List;
48
import junit.framework.Test;
49
import org.netbeans.core.startup.MainLookup;
50
import org.netbeans.core.startup.NbRepository;
51
import org.netbeans.junit.NbModuleSuite;
52
import org.netbeans.junit.NbTestCase;
53
import org.openide.filesystems.FileObject;
54
import org.openide.filesystems.FileUtil;
55
import org.openide.filesystems.Repository;
56
import org.openide.filesystems.Repository.LayersProvider;
57
import org.openide.util.Lookup;
58
59
/**
60
 *
61
 * @author Jaroslav Tulach <jtulach@netbeans.org>
62
 */
63
public class ContentProviderTest extends NbTestCase {
64
    public ContentProviderTest(String name) {
65
        super(name);
66
    }
67
    
68
    public static Test suite() {
69
        return NbModuleSuite.createConfiguration(ContentProviderTest.class)
70
            .gui(false).suite();
71
    }
72
    
73
    public void testBeforeRest() {
74
        FileObject fo = FileUtil.getConfigFile("foo/bar");
75
        assertNull("no foo/bar provided", fo);
76
    }
77
    
78
    public void testUsingNbRepositoryAndInit() {
79
        if (Repository.getDefault() instanceof NbRepository) {
80
            MainLookup.register(new MyProvider());
81
            return;
82
        }
83
        fail("Wrong repository: " + Repository.getDefault());
84
    }
85
    
86
    public void testCheckAFileFromOurLayer() {
87
        FileObject fo = FileUtil.getConfigFile("foo/bar");
88
        assertNotNull("foo/bar is provided", fo);
89
        assertEquals("value is val", "val", fo.getAttribute("x"));
90
    }
91
    
92
    public void testReturnEmptyLayers() throws Exception {
93
        MyProvider my = Lookup.getDefault().lookup(MyProvider.class);
94
        my.makeEmpty();
95
        FileObject fo = FileUtil.getConfigFile("foo/bar");
96
        assertNull("no foo/bar is provided anymore", fo);
97
        
98
    }
99
100
    public static final class MyProvider extends LayersProvider {
101
        private boolean empty;
102
        
103
        final void makeEmpty() {
104
            empty = true;
105
            refresh();
106
        }
107
        
108
        @Override
109
        protected void registerLayers(Collection<? super URL> context) {
110
            if (empty) {
111
                return;
112
            }
113
            context.add(ContentProviderTest.class.getResource("ContentProviderTest.xml"));
114
            assertFalse("No nulls", context.contains(null));
115
        }
116
    }
117
    
118
}
(-)a/ide.ergonomics/nbproject/project.xml (-1 / +1 lines)
Lines 115-121 Link Here
115
                    <build-prerequisite/>
115
                    <build-prerequisite/>
116
                    <compile-dependency/>
116
                    <compile-dependency/>
117
                    <run-dependency>
117
                    <run-dependency>
118
                        <specification-version>7.55</specification-version>
118
                        <specification-version>7.59</specification-version>
119
                    </run-dependency>
119
                    </run-dependency>
120
                </dependency>
120
                </dependency>
121
                <dependency>
121
                <dependency>
(-)a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/Installer.java (-2 lines)
Lines 43-49 Link Here
43
43
44
import org.netbeans.api.project.ui.OpenProjects;
44
import org.netbeans.api.project.ui.OpenProjects;
45
import org.netbeans.modules.ide.ergonomics.fod.FeatureManager;
45
import org.netbeans.modules.ide.ergonomics.fod.FeatureManager;
46
import org.netbeans.modules.ide.ergonomics.fod.FoDFileSystem;
47
import org.openide.modules.ModuleInstall;
46
import org.openide.modules.ModuleInstall;
48
import org.openide.util.Exceptions;
47
import org.openide.util.Exceptions;
49
48
Lines 57-63 Link Here
57
    @Override
56
    @Override
58
    public void restored() {
57
    public void restored() {
59
        WarmUp.init();
58
        WarmUp.init();
60
        FoDFileSystem.getInstance().initListener();
61
    }
59
    }
62
    
60
    
63
    @Override
61
    @Override
(-)a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/debugger/AttachTypeProxy.java (-2 / +2 lines)
Lines 49-55 Link Here
49
import org.netbeans.api.debugger.DebuggerManager;
49
import org.netbeans.api.debugger.DebuggerManager;
50
import org.netbeans.modules.ide.ergonomics.fod.ConfigurationPanel;
50
import org.netbeans.modules.ide.ergonomics.fod.ConfigurationPanel;
51
import org.netbeans.modules.ide.ergonomics.fod.FeatureInfo;
51
import org.netbeans.modules.ide.ergonomics.fod.FeatureInfo;
52
import org.netbeans.modules.ide.ergonomics.fod.FoDFileSystem;
52
import org.netbeans.modules.ide.ergonomics.fod.FoDLayersProvider;
53
import org.netbeans.spi.debugger.ui.AttachType;
53
import org.netbeans.spi.debugger.ui.AttachType;
54
import org.netbeans.spi.debugger.ui.Controller;
54
import org.netbeans.spi.debugger.ui.Controller;
55
import org.openide.filesystems.FileObject;
55
import org.openide.filesystems.FileObject;
Lines 74-80 Link Here
74
    }
74
    }
75
75
76
    public static AttachType create(FileObject fob) {
76
    public static AttachType create(FileObject fob) {
77
        FeatureInfo whichProvides = FoDFileSystem.getInstance().whichProvides(fob);
77
        FeatureInfo whichProvides = FoDLayersProvider.getInstance().whichProvides(fob);
78
        String displayName = (String) fob.getAttribute("displayName");
78
        String displayName = (String) fob.getAttribute("displayName");
79
        if (displayName == null) {
79
        if (displayName == null) {
80
            throw new IllegalArgumentException("No displayName attribute: " + fob);
80
            throw new IllegalArgumentException("No displayName attribute: " + fob);
(-)a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/FeatureAction.java (-1 / +1 lines)
Lines 68-74 Link Here
68
    }
68
    }
69
69
70
    public void actionPerformed(ActionEvent e) {
70
    public void actionPerformed(ActionEvent e) {
71
        FeatureInfo info = FoDFileSystem.getInstance().whichProvides(fo);
71
        FeatureInfo info = FoDLayersProvider.getInstance().whichProvides(fo);
72
        String n = Actions.cutAmpersand((String)fo.getAttribute("displayName")); // NOI18N
72
        String n = Actions.cutAmpersand((String)fo.getAttribute("displayName")); // NOI18N
73
        boolean success = Utilities.featureDialog(info, n, n);
73
        boolean success = Utilities.featureDialog(info, n, n);
74
        if (!success) {
74
        if (!success) {
(-)a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/FeatureInfo.java (-2 / +2 lines)
Lines 187-193 Link Here
187
                        fs = new XMLFileSystem(url);
187
                        fs = new XMLFileSystem(url);
188
                        return fs;
188
                        return fs;
189
                    } catch (SAXException ex) {
189
                    } catch (SAXException ex) {
190
                        FoDFileSystem.LOG.log(Level.SEVERE, "Cannot parse: " + url, ex);
190
                        FoDLayersProvider.LOG.log(Level.SEVERE, "Cannot parse: " + url, ex);
191
                        Exceptions.printStackTrace(ex);
191
                        Exceptions.printStackTrace(ex);
192
                    }
192
                    }
193
                }
193
                }
Lines 223-229 Link Here
223
                                try {
223
                                try {
224
                                    required[1] = e = XPathFactory.newInstance().newXPath().compile((String) r1);
224
                                    required[1] = e = XPathFactory.newInstance().newXPath().compile((String) r1);
225
                                } catch (XPathExpressionException ex) {
225
                                } catch (XPathExpressionException ex) {
226
                                    FoDFileSystem.LOG.log(Level.WARNING, "Cannot parse " + r1, ex);
226
                                    FoDLayersProvider.LOG.log(Level.WARNING, "Cannot parse " + r1, ex);
227
                                    continue;
227
                                    continue;
228
                                }
228
                                }
229
                            } else {
229
                            } else {
(-)a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/FeatureManager.java (-9 / +9 lines)
Lines 162-168 Link Here
162
     * @return
162
     * @return
163
     */
163
     */
164
    public static int dumpModules(Level withLevel, Level detailsLevel) {
164
    public static int dumpModules(Level withLevel, Level detailsLevel) {
165
        if (!FoDFileSystem.LOG.isLoggable(withLevel)) {
165
        if (!FoDLayersProvider.LOG.isLoggable(withLevel)) {
166
            return -1;
166
            return -1;
167
        }
167
        }
168
        int cnt = 0;
168
        int cnt = 0;
Lines 180-205 Link Here
180
                }
180
                }
181
            }
181
            }
182
            if (enabled.isEmpty() && disabled.isEmpty()) {
182
            if (enabled.isEmpty() && disabled.isEmpty()) {
183
                FoDFileSystem.LOG.log(withLevel, info.clusterName + " not present"); // NOTICES
183
                FoDLayersProvider.LOG.log(withLevel, info.clusterName + " not present"); // NOTICES
184
                continue;
184
                continue;
185
            }
185
            }
186
            if (enabled.isEmpty()) {
186
            if (enabled.isEmpty()) {
187
                FoDFileSystem.LOG.log(withLevel, info.clusterName + " disabled"); // NOTICES
187
                FoDLayersProvider.LOG.log(withLevel, info.clusterName + " disabled"); // NOTICES
188
                continue;
188
                continue;
189
            }
189
            }
190
            if (disabled.isEmpty()) {
190
            if (disabled.isEmpty()) {
191
                FoDFileSystem.LOG.log(withLevel, info.clusterName + " enabled"); // NOTICES
191
                FoDLayersProvider.LOG.log(withLevel, info.clusterName + " enabled"); // NOTICES
192
                cnt++;
192
                cnt++;
193
                continue;
193
                continue;
194
            }
194
            }
195
            FoDFileSystem.LOG.log(withLevel,
195
            FoDLayersProvider.LOG.log(withLevel,
196
                info.clusterName + " enabled " + enabled.size() + " disabled " + disabled.size()); // NOTICES
196
                info.clusterName + " enabled " + enabled.size() + " disabled " + disabled.size()); // NOTICES
197
            cnt++;
197
            cnt++;
198
            for (String cnb : disabled) {
198
            for (String cnb : disabled) {
199
                FoDFileSystem.LOG.log(detailsLevel, "- " + cnb); // NOI18N
199
                FoDLayersProvider.LOG.log(detailsLevel, "- " + cnb); // NOI18N
200
            }
200
            }
201
            for (String cnb : enabled) {
201
            for (String cnb : enabled) {
202
                FoDFileSystem.LOG.log(detailsLevel, "+ " + cnb); // NOI18N
202
                FoDLayersProvider.LOG.log(detailsLevel, "+ " + cnb); // NOI18N
203
            }
203
            }
204
        }
204
        }
205
        return cnt;
205
        return cnt;
Lines 292-303 Link Here
292
    }
292
    }
293
293
294
    private void fireChange() {
294
    private void fireChange() {
295
        FoDFileSystem.LOG.fine("Firing FeatureManager change"); // NOI18N
295
        FoDLayersProvider.LOG.fine("Firing FeatureManager change"); // NOI18N
296
        for (FeatureInfo f : features()) {
296
        for (FeatureInfo f : features()) {
297
            f.clearCache();
297
            f.clearCache();
298
        }
298
        }
299
        support.fireChange();
299
        support.fireChange();
300
        FoDFileSystem.LOG.fine("FeatureManager change delivered"); // NOI18N
300
        FoDLayersProvider.LOG.fine("FeatureManager change delivered"); // NOI18N
301
    }
301
    }
302
302
303
    /** Useful for testing */
303
    /** Useful for testing */
(-)a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/FindComponentModules.java (-2 / +2 lines)
Lines 165-171 Link Here
165
            }
165
            }
166
        }
166
        }
167
        if (res.size() > 1) {
167
        if (res.size() > 1) {
168
            FoDFileSystem.LOG.warning("No prefCNB found " + prefCNB + " using multiple " + res);
168
            FoDLayersProvider.LOG.warning("No prefCNB found " + prefCNB + " using multiple " + res);
169
        }
169
        }
170
        return res;
170
        return res;
171
    }
171
    }
Lines 261-267 Link Here
261
                        all.add (el);
261
                        all.add (el);
262
                        all.addAll (reqs);
262
                        all.addAll (reqs);
263
//                    } else {
263
//                    } else {
264
//                        FoDFileSystem.LOG.fine("Cannot enable " + el.getCodeName() + " broken deps: " + breaks); // NOI18N
264
//                        FoDLayersProvider.LOG.fine("Cannot enable " + el.getCodeName() + " broken deps: " + breaks); // NOI18N
265
//                        ignore.add(el.getCodeName());
265
//                        ignore.add(el.getCodeName());
266
//                    }
266
//                    }
267
                } else {
267
                } else {
(-)a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/FoDEditorOpened.java (-1 / +1 lines)
Lines 58-64 Link Here
58
    public void annotate(Set set, Lookup context) {
58
    public void annotate(Set set, Lookup context) {
59
        if (!anEditorIsOpened) {
59
        if (!anEditorIsOpened) {
60
            anEditorIsOpened = true;
60
            anEditorIsOpened = true;
61
            FoDFileSystem.getInstance().resultChanged(null);
61
            FoDLayersProvider.getInstance().resultChanged(null);
62
        }
62
        }
63
    }
63
    }
64
64
(-)a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/FoDFileSystem.java (-80 / +22 lines)
Lines 41-68 Link Here
41
 */
41
 */
42
package org.netbeans.modules.ide.ergonomics.fod;
42
package org.netbeans.modules.ide.ergonomics.fod;
43
43
44
import java.io.IOException;
45
import java.net.URL;
44
import java.net.URL;
46
import java.util.ArrayList;
45
import java.util.*;
47
import java.util.Arrays;
48
import java.util.HashSet;
49
import java.util.List;
50
import java.util.Set;
51
import java.util.logging.Level;
46
import java.util.logging.Level;
52
import java.util.logging.Logger;
47
import java.util.logging.Logger;
53
import javax.swing.event.ChangeEvent;
54
import javax.swing.event.ChangeListener;
55
import org.netbeans.core.startup.layers.LayerCacheManager;
56
import org.netbeans.spi.project.ProjectFactory;
48
import org.netbeans.spi.project.ProjectFactory;
57
import org.netbeans.spi.project.support.ant.AntBasedProjectType;
49
import org.netbeans.spi.project.support.ant.AntBasedProjectType;
58
import org.openide.filesystems.FileObject;
50
import org.openide.filesystems.FileObject;
59
import org.openide.filesystems.FileSystem;
51
import org.openide.filesystems.Repository;
60
import org.openide.filesystems.MultiFileSystem;
61
import org.openide.util.Lookup;
52
import org.openide.util.Lookup;
62
import org.openide.util.LookupEvent;
53
import org.openide.util.LookupEvent;
63
import org.openide.util.LookupListener;
54
import org.openide.util.LookupListener;
64
import org.openide.util.RequestProcessor;
55
import org.openide.util.RequestProcessor;
65
import org.openide.util.WeakListeners;
66
import org.openide.util.lookup.ServiceProvider;
56
import org.openide.util.lookup.ServiceProvider;
67
import org.openide.util.lookup.ServiceProviders;
57
import org.openide.util.lookup.ServiceProviders;
68
58
Lines 71-135 Link Here
71
 * @author Jirka Rechtacek
61
 * @author Jirka Rechtacek
72
 */
62
 */
73
@ServiceProviders({
63
@ServiceProviders({
74
    @ServiceProvider(service=FileSystem.class),
64
    @ServiceProvider(service=Repository.LayersProvider.class),
75
    @ServiceProvider(service=FoDFileSystem.class)
65
    @ServiceProvider(service=FoDLayersProvider.class)
76
})
66
})
77
public final class FoDFileSystem extends MultiFileSystem
67
public final class FoDLayersProvider extends Repository.LayersProvider
78
implements Runnable, ChangeListener, LookupListener {
68
implements LookupListener, Runnable {
79
    private static final LayerCacheManager manager = LayerCacheManager.create("all-ergonomics.dat"); // NOI18N
69
    final static Logger LOG = Logger.getLogger (FoDLayersProvider.class.getPackage().getName());
80
    final static Logger LOG = Logger.getLogger (FoDFileSystem.class.getPackage().getName());
81
    private static RequestProcessor RP = new RequestProcessor("Ergonomics"); // NOI18N
70
    private static RequestProcessor RP = new RequestProcessor("Ergonomics"); // NOI18N
82
    private RequestProcessor.Task refresh = RP.create(this, true);
71
    private RequestProcessor.Task refresh = RP.create(this, true);
83
    private Lookup.Result<ProjectFactory> factories;
72
    private Lookup.Result<ProjectFactory> factories;
84
    private Lookup.Result<?> ants;
73
    private Lookup.Result<?> ants;
85
    private boolean forcedRefresh;
86
    private final ChangeListener weakL;
87
74
88
    public FoDFileSystem() {
75
    public static FoDLayersProvider getInstance() {
89
        setPropagateMasks(true);
76
        return Lookup.getDefault().lookup(FoDLayersProvider.class);
90
        weakL = WeakListeners.change(this, FeatureManager.getInstance());
91
        FileSystem fs;
92
        try {
93
            fs = manager.loadCache();
94
            if (fs != null) {
95
                LOG.fine("Using cached layer"); // NOI18N
96
                setDelegates(fs);
97
                return;
98
            }
99
        } catch (IOException ex) {
100
            LOG.log(Level.WARNING, "Cannot read cache", ex); // NOI18N
101
        }
102
        refresh();
103
    }
104
105
    public static FoDFileSystem getInstance() {
106
        return Lookup.getDefault().lookup(FoDFileSystem.class);
107
    }
108
    
109
    public void initListener() {
110
        FeatureManager.getInstance().addChangeListener(weakL);
111
    }
112
113
    public void refresh() {
114
        refresh.schedule(0);
115
        refresh.waitFinished();
116
    }
117
    public void refreshForce() {
118
        forcedRefresh = true;
119
        refresh.schedule(0);
120
        refresh.waitFinished();
121
    }
122
123
    public void waitFinished() {
124
        refresh.waitFinished();
125
    }
77
    }
126
78
127
    @Override
79
    @Override
128
    public void run() {
80
    protected void registerLayers(Collection<? super URL> context) {
129
        boolean empty = true;
81
        boolean empty = true;
130
        LOG.fine("collecting layers"); // NOI18N
82
        LOG.fine("collecting layers"); // NOI18N
131
        List<URL> urls = new ArrayList<URL>();
83
        List<URL> urls = new ArrayList<URL>();
132
        urls.add(0, FoDFileSystem.class.getResource("common.xml")); // NOI18N
84
        urls.add(0, FoDLayersProvider.class.getResource("common.xml")); // NOI18N
133
        for (FeatureInfo info : FeatureManager.features()) {
85
        for (FeatureInfo info : FeatureManager.features()) {
134
            if (!info.isPresent()) {
86
            if (!info.isPresent()) {
135
                continue;
87
                continue;
Lines 144-169 Link Here
144
        }
96
        }
145
        if (empty && noAdditionalProjects() && !FoDEditorOpened.anEditorIsOpened) {
97
        if (empty && noAdditionalProjects() && !FoDEditorOpened.anEditorIsOpened) {
146
            LOG.fine("adding default layer"); // NOI18N
98
            LOG.fine("adding default layer"); // NOI18N
147
            urls.add(0, FoDFileSystem.class.getResource("default.xml")); // NOI18N
99
            urls.add(0, FoDLayersProvider.class.getResource("default.xml")); // NOI18N
148
        }
149
        if (forcedRefresh) {
150
            forcedRefresh = false;
151
            LOG.log(Level.INFO, "Forced refresh. Setting delegates to empty"); // NOI18N
152
            setDelegates();
153
            LOG.log(Level.INFO, "New delegates count: {0}", urls.size()); // NOI18N
154
            LOG.log(Level.INFO, "{0}", urls); // NOI18N
155
        }
100
        }
156
        LOG.log(Level.FINE, "delegating to {0} layers", urls.size()); // NOI18N
101
        LOG.log(Level.FINE, "delegating to {0} layers", urls.size()); // NOI18N
102
        context.addAll(urls);
157
        LOG.log(Level.FINEST, "{0}", urls); // NOI18N
103
        LOG.log(Level.FINEST, "{0}", urls); // NOI18N
158
159
        try {
160
            FileSystem fs = getDelegates().length == 0 ?
161
                manager.createEmptyFileSystem() : getDelegates()[0];
162
            fs = manager.store(fs, urls);
163
            setDelegates(fs);
164
        } catch (IOException ex) {
165
            LOG.log(Level.WARNING, "Cannot save cache", ex);
166
        }
167
        LOG.fine("done");
104
        LOG.fine("done");
168
        FeatureManager.dumpModules();
105
        FeatureManager.dumpModules();
169
    }
106
    }
Lines 192-204 Link Here
192
    }
129
    }
193
130
194
    @Override
131
    @Override
195
    public void stateChanged(ChangeEvent e) {
132
    public void resultChanged(LookupEvent ev) {
196
        refresh.schedule(500);
133
        refresh.schedule(500);
197
    }
134
    }
198
135
    public void refreshForce() {
136
        super.refresh();
137
    }
199
    @Override
138
    @Override
200
    public void resultChanged(LookupEvent ev) {
139
    public void run() {
201
        refresh.schedule(0);
140
        super.refresh();
141
    }
142
    public void waitFinished() {
143
        refresh.waitFinished();
202
    }
144
    }
203
145
204
    private boolean noAdditionalProjects() {
146
    private boolean noAdditionalProjects() {
(-)a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/FodDataObjectFactory.java (-6 / +6 lines)
Lines 82-88 Link Here
82
    
82
    
83
    private FodDataObjectFactory(FileObject fo) {
83
    private FodDataObjectFactory(FileObject fo) {
84
        this.definition = fo;
84
        this.definition = fo;
85
        this.info = FoDFileSystem.getInstance().whichProvides(definition);
85
        this.info = FoDLayersProvider.getInstance().whichProvides(definition);
86
    }
86
    }
87
87
88
88
Lines 154-163 Link Here
154
        }
154
        }
155
155
156
        private void delegate(boolean open) {
156
        private void delegate(boolean open) {
157
            FeatureInfo info = FoDFileSystem.getInstance().whichProvides(definition);
157
            FeatureInfo info = FoDLayersProvider.getInstance().whichProvides(definition);
158
            String msg = NbBundle.getMessage(FodDataObjectFactory.class, "MSG_Opening_File", fo.getNameExt());
158
            String msg = NbBundle.getMessage(FodDataObjectFactory.class, "MSG_Opening_File", fo.getNameExt());
159
159
160
            FoDFileSystem.LOG.log(Level.FINER, "Opening file {0}", this);
160
            FoDLayersProvider.LOG.log(Level.FINER, "Opening file {0}", this);
161
            this.open = open;
161
            this.open = open;
162
            boolean success = Utilities.featureDialog(info, msg, msg);
162
            boolean success = Utilities.featureDialog(info, msg, msg);
163
            if (success) {
163
            if (success) {
Lines 170-176 Link Here
170
            ignore.add(getPrimaryFile());
170
            ignore.add(getPrimaryFile());
171
            try {
171
            try {
172
                DataObject obj = DataObject.find(fo);
172
                DataObject obj = DataObject.find(fo);
173
                FoDFileSystem.LOG.log(Level.FINER, "finishOpen {0}", obj);
173
                FoDLayersProvider.LOG.log(Level.FINER, "finishOpen {0}", obj);
174
                Class<?> what = open ? OpenCookie.class : EditCookie.class;
174
                Class<?> what = open ? OpenCookie.class : EditCookie.class;
175
                Object oc = obj.getLookup().lookup(what);
175
                Object oc = obj.getLookup().lookup(what);
176
                if (oc == this) {
176
                if (oc == this) {
Lines 193-200 Link Here
193
193
194
        @Override
194
        @Override
195
        public void stateChanged(ChangeEvent e) {
195
        public void stateChanged(ChangeEvent e) {
196
            FeatureInfo info = FoDFileSystem.getInstance().whichProvides(definition);
196
            FeatureInfo info = FoDLayersProvider.getInstance().whichProvides(definition);
197
            FoDFileSystem.LOG.log(Level.FINER, "Refresh state of {0}", this);
197
            FoDLayersProvider.LOG.log(Level.FINER, "Refresh state of {0}", this);
198
            ignore.add(getPrimaryFile());
198
            ignore.add(getPrimaryFile());
199
            if (info == null || info.isEnabled()) {
199
            if (info == null || info.isEnabled()) {
200
                dispose();
200
                dispose();
(-)a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/ModulesActivator.java (-1 / +1 lines)
Lines 111-117 Link Here
111
            progressMonitor.onError(ex.getLocalizedMessage());
111
            progressMonitor.onError(ex.getLocalizedMessage());
112
            Logger.getLogger(ModulesActivator.class.getName()).warning(ex.getMessage());
112
            Logger.getLogger(ModulesActivator.class.getName()).warning(ex.getMessage());
113
        } finally {
113
        } finally {
114
            FoDFileSystem.getInstance().refresh();
114
            FoDLayersProvider.getInstance().refreshForce();
115
        }
115
        }
116
    }
116
    }
117
    
117
    
(-)a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/ModulesInstaller.java (-2 / +2 lines)
Lines 128-134 Link Here
128
        }
128
        }
129
        
129
        
130
        if (success) {
130
        if (success) {
131
            FoDFileSystem.getInstance().refresh();
131
            FoDLayersProvider.getInstance().refreshForce();
132
        }
132
        }
133
        
133
        
134
        return success;
134
        return success;
Lines 193-199 Link Here
193
                    );
193
                    );
194
            DialogDisplayer.getDefault ().notifyLater (nd);
194
            DialogDisplayer.getDefault ().notifyLater (nd);
195
        } finally {
195
        } finally {
196
            FoDFileSystem.getInstance().refresh();
196
            FoDLayersProvider.getInstance().refreshForce();
197
        }
197
        }
198
    }
198
    }
199
    
199
    
(-)a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/OpenAdvancedAction.java (-1 / +1 lines)
Lines 78-84 Link Here
78
        if (mimeDefinition == null) {
78
        if (mimeDefinition == null) {
79
            return;
79
            return;
80
        }
80
        }
81
        final FeatureInfo info = FoDFileSystem.getInstance().whichProvides(mimeDefinition);
81
        final FeatureInfo info = FoDLayersProvider.getInstance().whichProvides(mimeDefinition);
82
        if (info == null || info.isEnabled()) {
82
        if (info == null || info.isEnabled()) {
83
            return;
83
            return;
84
        }
84
        }
(-)a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/newproject/DescriptionStep.java (-7 / +11 lines)
Lines 43-48 Link Here
43
 */
43
 */
44
package org.netbeans.modules.ide.ergonomics.newproject;
44
package org.netbeans.modules.ide.ergonomics.newproject;
45
45
46
import java.util.concurrent.ExecutionException;
46
import org.netbeans.modules.ide.ergonomics.fod.FindComponentModules;
47
import org.netbeans.modules.ide.ergonomics.fod.FindComponentModules;
47
import org.netbeans.modules.ide.ergonomics.fod.ModulesInstaller;
48
import org.netbeans.modules.ide.ergonomics.fod.ModulesInstaller;
48
import java.awt.Component;
49
import java.awt.Component;
Lines 68-74 Link Here
68
import org.netbeans.api.progress.ProgressHandle;
69
import org.netbeans.api.progress.ProgressHandle;
69
import org.netbeans.modules.ide.ergonomics.ServerWizardProviderProxy;
70
import org.netbeans.modules.ide.ergonomics.ServerWizardProviderProxy;
70
import org.netbeans.modules.ide.ergonomics.fod.ConfigurationPanel;
71
import org.netbeans.modules.ide.ergonomics.fod.ConfigurationPanel;
71
import org.netbeans.modules.ide.ergonomics.fod.FoDFileSystem;
72
import org.netbeans.modules.ide.ergonomics.fod.FoDLayersProvider;
72
import org.netbeans.modules.ide.ergonomics.fod.FeatureInfo;
73
import org.netbeans.modules.ide.ergonomics.fod.FeatureInfo;
73
import org.netbeans.modules.ide.ergonomics.fod.FeatureManager;
74
import org.netbeans.modules.ide.ergonomics.fod.FeatureManager;
74
import org.netbeans.spi.server.ServerWizardProvider;
75
import org.netbeans.spi.server.ServerWizardProvider;
Lines 109-115 Link Here
109
            configPanel = new ConfigurationPanel(new Callable<JComponent>() {
110
            configPanel = new ConfigurationPanel(new Callable<JComponent>() {
110
                @Override
111
                @Override
111
                public JComponent call() throws Exception {
112
                public JComponent call() throws Exception {
112
                    FoDFileSystem.getInstance().refresh();
113
                    FoDLayersProvider.getInstance().refreshForce();
113
                    waitForDelegateWizard();
114
                    waitForDelegateWizard();
114
                    return new JLabel(" ");
115
                    return new JLabel(" ");
115
                }
116
                }
Lines 182-188 Link Here
182
            forEnable = elems;
183
            forEnable = elems;
183
            fireChange ();
184
            fireChange ();
184
        } else {
185
        } else {
185
            FoDFileSystem.getInstance().refresh();
186
            FoDLayersProvider.getInstance().refreshForce();
186
            waitForDelegateWizard ();
187
            waitForDelegateWizard ();
187
            SwingUtilities.invokeLater(new Runnable() {
188
            SwingUtilities.invokeLater(new Runnable() {
188
                public void run() {
189
                public void run() {
Lines 207-213 Link Here
207
        Object o = settings.getProperty (FeatureOnDemandWizardIterator.CHOSEN_TEMPLATE);
208
        Object o = settings.getProperty (FeatureOnDemandWizardIterator.CHOSEN_TEMPLATE);
208
        assert o != null && o instanceof FileObject : o + " is not null and instanceof FileObject.";
209
        assert o != null && o instanceof FileObject : o + " is not null and instanceof FileObject.";
209
        FileObject fileObject = (FileObject) o;
210
        FileObject fileObject = (FileObject) o;
210
        info = FoDFileSystem.getInstance ().whichProvides(fileObject);
211
        info = FoDLayersProvider.getInstance ().whichProvides(fileObject);
211
        assert info != null : "No info for " + fileObject;
212
        assert info != null : "No info for " + fileObject;
212
        finder = new FindComponentModules(info);
213
        finder = new FindComponentModules(info);
213
    }
214
    }
Lines 228-235 Link Here
228
        WizardDescriptor.InstantiatingIterator<?> iterator = null;
229
        WizardDescriptor.InstantiatingIterator<?> iterator = null;
229
        int i = 0;
230
        int i = 0;
230
        while (fo == null || iterator == null) {
231
        while (fo == null || iterator == null) {
231
            FoDFileSystem.getInstance().refresh();
232
            try {
232
            FoDFileSystem.getInstance().waitFinished();
233
                FoDLayersProvider.getInstance().refreshForce();
234
            } catch (Exception ex) {
235
                Exceptions.printStackTrace(ex);
236
            }
233
            // hot-fixed wizard providers - temporary
237
            // hot-fixed wizard providers - temporary
234
            if (templateResource.startsWith("Servers/WizardProvider")) {
238
            if (templateResource.startsWith("Servers/WizardProvider")) {
235
                try {
239
                try {
Lines 287-293 Link Here
287
                }
291
                }
288
                LOG.info("Forcing refresh"); // NOI18N
292
                LOG.info("Forcing refresh"); // NOI18N
289
                // force refresh for the filesystem
293
                // force refresh for the filesystem
290
                FoDFileSystem.getInstance().refreshForce();
294
                FoDLayersProvider.getInstance().refreshForce();
291
                LOG.info("Done with refresh"); // NOI18N
295
                LOG.info("Done with refresh"); // NOI18N
292
296
293
                FileObject fake = FileUtil.getConfigFile(templateResource);
297
                FileObject fake = FileUtil.getConfigFile(templateResource);
(-)a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/newproject/EnableStep.java (-3 / +3 lines)
Lines 61-67 Link Here
61
import org.netbeans.api.progress.ProgressHandleFactory;
61
import org.netbeans.api.progress.ProgressHandleFactory;
62
import org.netbeans.modules.ide.ergonomics.fod.FeatureInfo;
62
import org.netbeans.modules.ide.ergonomics.fod.FeatureInfo;
63
import org.netbeans.modules.ide.ergonomics.fod.FeatureManager;
63
import org.netbeans.modules.ide.ergonomics.fod.FeatureManager;
64
import org.netbeans.modules.ide.ergonomics.fod.FoDFileSystem;
64
import org.netbeans.modules.ide.ergonomics.fod.FoDLayersProvider;
65
import org.openide.WizardDescriptor;
65
import org.openide.WizardDescriptor;
66
import org.openide.WizardDescriptor.Panel;
66
import org.openide.WizardDescriptor.Panel;
67
import org.openide.filesystems.FileObject;
67
import org.openide.filesystems.FileObject;
Lines 125-131 Link Here
125
                    RequestProcessor.Task enable = activator.getEnableTask ();
125
                    RequestProcessor.Task enable = activator.getEnableTask ();
126
                    enable.schedule (0);
126
                    enable.schedule (0);
127
                    enable.waitFinished ();
127
                    enable.waitFinished ();
128
                    FoDFileSystem.getInstance().refresh();
128
                    FoDLayersProvider.getInstance().refreshForce();
129
                    waitForDelegateWizard ();
129
                    waitForDelegateWizard ();
130
                }
130
                }
131
            }
131
            }
Lines 153-159 Link Here
153
        Object templateO = settings.getProperty (FeatureOnDemandWizardIterator.CHOSEN_TEMPLATE);
153
        Object templateO = settings.getProperty (FeatureOnDemandWizardIterator.CHOSEN_TEMPLATE);
154
        assert templateO != null && templateO instanceof FileObject : templateO + " is not null and instanceof FileObject.";
154
        assert templateO != null && templateO instanceof FileObject : templateO + " is not null and instanceof FileObject.";
155
        FileObject templateFO = (FileObject) templateO;
155
        FileObject templateFO = (FileObject) templateO;
156
        FeatureInfo info = FoDFileSystem.getInstance().whichProvides(templateFO);
156
        FeatureInfo info = FoDLayersProvider.getInstance().whichProvides(templateFO);
157
        RequestProcessor.Task t = FeatureManager.getInstance().create(doEnable(info));
157
        RequestProcessor.Task t = FeatureManager.getInstance().create(doEnable(info));
158
        t.schedule(0);
158
        t.schedule(0);
159
    }
159
    }
(-)a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/newproject/FeatureOnDemandWizardIterator.java (-2 / +2 lines)
Lines 53-59 Link Here
53
import javax.swing.JComponent;
53
import javax.swing.JComponent;
54
import javax.swing.event.ChangeListener;
54
import javax.swing.event.ChangeListener;
55
import org.netbeans.api.progress.ProgressHandle;
55
import org.netbeans.api.progress.ProgressHandle;
56
import org.netbeans.modules.ide.ergonomics.fod.FoDFileSystem;
56
import org.netbeans.modules.ide.ergonomics.fod.FoDLayersProvider;
57
import org.openide.WizardDescriptor;
57
import org.openide.WizardDescriptor;
58
import org.openide.WizardDescriptor.InstantiatingIterator;
58
import org.openide.WizardDescriptor.InstantiatingIterator;
59
import org.openide.WizardDescriptor.ProgressInstantiatingIterator;
59
import org.openide.WizardDescriptor.ProgressInstantiatingIterator;
Lines 95-101 Link Here
95
    
95
    
96
    private static WizardDescriptor.InstantiatingIterator getRealNewMakeProjectWizardIterator (FileObject template) {
96
    private static WizardDescriptor.InstantiatingIterator getRealNewMakeProjectWizardIterator (FileObject template) {
97
        WizardDescriptor.InstantiatingIterator res = null;
97
        WizardDescriptor.InstantiatingIterator res = null;
98
        if (FoDFileSystem.getInstance().getDelegateFileSystem (template) != null) {
98
        if (FoDLayersProvider.getInstance().getDelegateFileSystem (template) != null) {
99
            return null;
99
            return null;
100
        }
100
        }
101
        FileObject fo = FileUtil.getConfigFile(template.getPath ());
101
        FileObject fo = FileUtil.getConfigFile(template.getPath ());
(-)a/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/AdditionalAntBasedTest.java (-1 / +1 lines)
Lines 120-126 Link Here
120
120
121
        assertNotNull("Ant found", f);
121
        assertNotNull("Ant found", f);
122
        LOG.info("waiting for FoDFileSystem to be updated");
122
        LOG.info("waiting for FoDFileSystem to be updated");
123
        FoDFileSystem.getInstance().waitFinished();
123
        FoDLayersProvider.getInstance().waitFinished();
124
        LOG.info("waiting for FoDFileSystem to be waitFinished is over");
124
        LOG.info("waiting for FoDFileSystem to be waitFinished is over");
125
125
126
        for (int cnt = 0; cnt < 5; cnt++) {
126
        for (int cnt = 0; cnt < 5; cnt++) {
(-)a/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/AdditionalProjectFactoryTest.java (-1 / +1 lines)
Lines 103-109 Link Here
103
        Factory f = Lookup.getDefault().lookup(Factory.class);
103
        Factory f = Lookup.getDefault().lookup(Factory.class);
104
        assertNotNull("Factory found", f);
104
        assertNotNull("Factory found", f);
105
        LOG.info("Factory found");
105
        LOG.info("Factory found");
106
        FoDFileSystem.getInstance().waitFinished();
106
        FoDLayersProvider.getInstance().waitFinished();
107
        LOG.info("Refresh finished");
107
        LOG.info("Refresh finished");
108
        
108
        
109
        for (int i = 0; i < 100; i++) {
109
        for (int i = 0; i < 100; i++) {
(-)a/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/EnablingAutoloadLeavesFeatureDisabledTest.java (-2 / +1 lines)
Lines 155-162 Link Here
155
            ParseXMLContentTest.class.getResource("TestBundle4.properties")
155
            ParseXMLContentTest.class.getResource("TestBundle4.properties")
156
        );
156
        );
157
        ic.add(info);
157
        ic.add(info);
158
        FoDFileSystem.getInstance().refresh();
158
        FoDLayersProvider.getInstance().refreshForce();
159
        FoDFileSystem.getInstance().waitFinished();
160
    }
159
    }
161
160
162
161
(-)a/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/FodDataObjectFactoryTest.java (-2 / +1 lines)
Lines 154-161 Link Here
154
            ParseXMLContentTest.class.getResource("TestBundle.properties")
154
            ParseXMLContentTest.class.getResource("TestBundle.properties")
155
        );
155
        );
156
        ic.add(info);
156
        ic.add(info);
157
        FoDFileSystem.getInstance().refresh();
157
        FoDLayersProvider.getInstance().refreshForce();
158
        FoDFileSystem.getInstance().waitFinished();
159
    }
158
    }
160
159
161
160
(-)a/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/FodDataObjectXMLFactoryTest.java (-2 / +1 lines)
Lines 160-167 Link Here
160
            ParseXMLContentTest.class.getResource("TestBundle.properties")
160
            ParseXMLContentTest.class.getResource("TestBundle.properties")
161
        );
161
        );
162
        ic.add(info);
162
        ic.add(info);
163
        FoDFileSystem.getInstance().refresh();
163
        FoDLayersProvider.getInstance().refreshForce();
164
        FoDFileSystem.getInstance().waitFinished();
165
    }
164
    }
166
165
167
166
(-)a/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/GeneralActionTest.java (-1 / +1 lines)
Lines 122-128 Link Here
122
        root = FileUtil.toFileObject(getWorkDir());
122
        root = FileUtil.toFileObject(getWorkDir());
123
        assertNotNull("fileobject found", root);
123
        assertNotNull("fileobject found", root);
124
        
124
        
125
        FoDFileSystem.getInstance().refresh();
125
        FoDLayersProvider.getInstance().refreshForce();
126
126
127
        actionFile = FileUtil.getConfigFile("Actions/System/org-netbeans-modules-autoupdate-ui-actions-PluginManagerAction.instance");
127
        actionFile = FileUtil.getConfigFile("Actions/System/org-netbeans-modules-autoupdate-ui-actions-PluginManagerAction.instance");
128
        assertNotNull("testing layer is loaded: ", actionFile);
128
        assertNotNull("testing layer is loaded: ", actionFile);
(-)a/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/OpenEditorEnablesEditMenuFactoryTest.java (-1 / +1 lines)
Lines 151-157 Link Here
151
            }
151
            }
152
        });
152
        });
153
        LOG.info("waitFinished");
153
        LOG.info("waitFinished");
154
        FoDFileSystem.getInstance().waitFinished();
154
        FoDLayersProvider.getInstance().waitFinished();
155
155
156
        FileObject fo = null;
156
        FileObject fo = null;
157
        for (int i = 0; i < 100; i++) {
157
        for (int i = 0; i < 100; i++) {
(-)a/openide.filesystems/apichanges.xml (+19 lines)
Lines 49-54 Link Here
49
        <apidef name="filesystems">Filesystems API</apidef>
49
        <apidef name="filesystems">Filesystems API</apidef>
50
    </apidefs>
50
    </apidefs>
51
    <changes>
51
    <changes>
52
        <change id="LayersProvider">
53
            <api name="filesystems"/>
54
            <summary>SPI for Additions to System File System</summary>
55
            <version major="7" minor="59"/>
56
            <date year="2012" month="2" day="3"/>
57
            <author login="jtulach"/>
58
            <compatibility addition="yes" deprecation="yes"/>
59
            <description>
60
                <p>
61
                    Those who wish to influence content of 
62
                    <a href="@TOP@/org/openide/filesystems/FileUtil.html#getConfigRoot()">
63
                    configuration file system</a> have an easier
64
                    <a href="@TOP@/org/openide/filesystems/Repository.LayersProvider.html">
65
                    way</a> now.
66
                </p>
67
            </description>
68
            <class package="org.openide.filesystems" name="Repository"/>
69
            <issue number="198508"/>
70
        </change>
52
        <change id="MIMEResolver.Registrations">
71
        <change id="MIMEResolver.Registrations">
53
            <api name="filesystems"/>
72
            <api name="filesystems"/>
54
            <summary>Annotations to declare MIME type</summary>
73
            <summary>Annotations to declare MIME type</summary>
(-)a/openide.filesystems/manifest.mf (-1 / +1 lines)
Lines 2-6 Link Here
2
OpenIDE-Module: org.openide.filesystems
2
OpenIDE-Module: org.openide.filesystems
3
OpenIDE-Module-Localizing-Bundle: org/openide/filesystems/Bundle.properties
3
OpenIDE-Module-Localizing-Bundle: org/openide/filesystems/Bundle.properties
4
OpenIDE-Module-Layer: org/openide/filesystems/resources/layer.xml
4
OpenIDE-Module-Layer: org/openide/filesystems/resources/layer.xml
5
OpenIDE-Module-Specification-Version: 7.58
5
OpenIDE-Module-Specification-Version: 7.59
6
6
(-)a/openide.filesystems/src/org/openide/filesystems/Repository.java (-28 / +99 lines)
Lines 56-68 Link Here
56
import java.io.ObjectOutputStream;
56
import java.io.ObjectOutputStream;
57
import java.io.Serializable;
57
import java.io.Serializable;
58
import java.net.URL;
58
import java.net.URL;
59
import java.util.ArrayList;
59
import java.util.*;
60
import java.util.Enumeration;
60
import java.util.concurrent.Future;
61
import java.util.HashSet;
62
import java.util.Hashtable;
63
import java.util.Iterator;
64
import java.util.List;
65
import java.util.Vector;
66
import java.util.concurrent.atomic.AtomicReference;
61
import java.util.concurrent.atomic.AtomicReference;
67
import java.util.jar.Manifest;
62
import java.util.jar.Manifest;
68
import java.util.logging.Level;
63
import java.util.logging.Level;
Lines 72-77 Link Here
72
import org.openide.util.LookupListener;
67
import org.openide.util.LookupListener;
73
import org.openide.util.NbCollections;
68
import org.openide.util.NbCollections;
74
import org.openide.util.io.NbMarshalledObject;
69
import org.openide.util.io.NbMarshalledObject;
70
import org.openide.util.lookup.ServiceProvider;
75
71
76
/**
72
/**
77
 * Holder for NetBeans default (system, configuration) filesystem, used for most
73
 * Holder for NetBeans default (system, configuration) filesystem, used for most
Lines 143-148 Link Here
143
139
144
        return repository;
140
        return repository;
145
    }
141
    }
142
    
143
    /** Contributes to content of {@link #getDefaultFileSystem() system file system} 
144
     * (which influences structure under {@link FileUtil#getConfigRoot()}). The
145
     * method {@link #registerLayers(java.util.Collection)} 
146
     * is called during initialization of {@link Repository} and 
147
     * implementors (registered via {@link ServiceProvider} annotation) may
148
     * add their <em>layers</em> (later processed via {@link XMLFileSystem}) into
149
     * the general collection of existing providers.
150
     * <p class="nonnormative">
151
     * The list of <em>layers</em> as well as their content may be cached.
152
     * In a typical NetBeans Platform application, the cache remains until
153
     * list of <a href="@org-openide-modules@/org/openide/modules/ModuleInfo.html">modules</a>
154
     * and their enabled state remain the same. While it does, the {@link LayersProvider}s
155
     * are not queried again.
156
     * </p>
157
     * @since 7.59
158
     */
159
    public static abstract class LayersProvider {
160
        /** Allows providers to add their additions to the structure
161
         * beneath {@link FileUtil#getConfigRoot()}. The method is
162
         * supposed to collect all additional layers and {@link Collection#add(java.lang.Object) add}
163
         * them into the <code>context</code> collection. The provided
164
         * layers will be processed by {@link XMLFileSystem}-like manner later.
165
         * 
166
         * @param context the context where to register the additions
167
         */
168
        protected abstract void registerLayers(Collection<? super URL> context);
169
        
170
        /** Method to call when set of URLs returned from the {@link #layers()}
171
         * method changed and there is a need to refresh it. Refresh is very likely 
172
         * a time consuming task - consider invoking it on a background thread and
173
         * don't hold any locks while calling the method
174
         */
175
        protected final void refresh() {
176
            Repository.getDefault().refreshAdditionalLayers();
177
        }
178
    }
179
180
    /** Methods that tells {@link Repository} subclasses to refresh list of
181
     * URLs provided by {@link LayersProvider}s.
182
     * @since 7.59
183
     */
184
    protected void refreshAdditionalLayers() {
185
        if (getDefaultFileSystem() instanceof MainFS) {
186
            ((MainFS)getDefaultFileSystem()).refreshLayers();
187
        }
188
    }
189
    
190
    /** Allows subclasses registered as {@link Repository#getDefault()} to 
191
     * find out list of URLs for a given provider. The method just calls
192
     * {@link LayersProvider#layers()}.
193
     * 
194
     * @param p the provider.
195
     * @return ordered list of URLs
196
     * @since 7.59
197
     */
198
    protected final List<? extends URL> findLayers(LayersProvider p) {
199
        if (this != Repository.getDefault()) {
200
            return Collections.emptyList();
201
        }
202
        List<URL> urls = new ArrayList<URL>();
203
        p.registerLayers(urls);
204
        return urls;
205
    }
146
206
147
    private static final class MainFS extends MultiFileSystem implements LookupListener {
207
    private static final class MainFS extends MultiFileSystem implements LookupListener {
148
        private static final Lookup.Result<FileSystem> ALL = Lookup.getDefault().lookupResult(FileSystem.class);
208
        private static final Lookup.Result<FileSystem> ALL = Lookup.getDefault().lookupResult(FileSystem.class);
Lines 151-179 Link Here
151
211
152
        public MainFS() {
212
        public MainFS() {
153
            ALL.addLookupListener(this);
213
            ALL.addLookupListener(this);
214
            refreshLayers();
215
        }
216
        
217
        final void refreshLayers() {
154
            List<URL> layerUrls = new ArrayList<URL>();
218
            List<URL> layerUrls = new ArrayList<URL>();
155
            ClassLoader l = Thread.currentThread().getContextClassLoader();
156
            try {
219
            try {
157
                for (URL manifest : NbCollections.iterable(l.getResources("META-INF/MANIFEST.MF"))) { // NOI18N
220
                provideLayer(layerUrls);
158
                    InputStream is = manifest.openStream();
159
                    try {
160
                        Manifest mani = new Manifest(is);
161
                        String layerLoc = mani.getMainAttributes().getValue("OpenIDE-Module-Layer"); // NOI18N
162
                        if (layerLoc != null) {
163
                            URL layer = l.getResource(layerLoc);
164
                            if (layer != null) {
165
                                layerUrls.add(layer);
166
                            } else {
167
                                LOG.warning("No such layer: " + layerLoc);
168
                            }
169
                        }
170
                    } finally {
171
                        is.close();
172
                    }
173
                }
174
                for (URL generatedLayer : NbCollections.iterable(l.getResources("META-INF/generated-layer.xml"))) { // NOI18N
175
                    layerUrls.add(generatedLayer);
176
                }
177
                layers.setXmlUrls(layerUrls.toArray(new URL[layerUrls.size()]));
221
                layers.setXmlUrls(layerUrls.toArray(new URL[layerUrls.size()]));
178
                LOG.log(Level.FINE, "Loading classpath layers: {0}", layerUrls);
222
                LOG.log(Level.FINE, "Loading classpath layers: {0}", layerUrls);
179
            } catch (Exception x) {
223
            } catch (Exception x) {
Lines 182-187 Link Here
182
            resultChanged(null); // run after add listener - see PN1 in #26338
226
            resultChanged(null); // run after add listener - see PN1 in #26338
183
        }
227
        }
184
228
229
        private void provideLayer(List<URL> layerUrls) throws IOException {
230
            ClassLoader l = Thread.currentThread().getContextClassLoader();
231
            for (URL manifest : NbCollections.iterable(l.getResources("META-INF/MANIFEST.MF"))) { // NOI18N
232
                InputStream is = manifest.openStream();
233
                try {
234
                    Manifest mani = new Manifest(is);
235
                    String layerLoc = mani.getMainAttributes().getValue("OpenIDE-Module-Layer"); // NOI18N
236
                    if (layerLoc != null) {
237
                        URL layer = l.getResource(layerLoc);
238
                        if (layer != null) {
239
                            layerUrls.add(layer);
240
                        } else {
241
                            LOG.warning("No such layer: " + layerLoc);
242
                        }
243
                    }
244
                } finally {
245
                    is.close();
246
                }
247
            }
248
            for (URL generatedLayer : NbCollections.iterable(l.getResources("META-INF/generated-layer.xml"))) { // NOI18N
249
                layerUrls.add(generatedLayer);
250
            }
251
            for (LayersProvider p : Lookup.getDefault().lookupAll(LayersProvider.class)) {
252
                p.registerLayers(layerUrls);
253
            }
254
        }
255
185
        private static FileSystem[] computeDelegates() {
256
        private static FileSystem[] computeDelegates() {
186
            List<FileSystem> arr = new ArrayList<FileSystem>();
257
            List<FileSystem> arr = new ArrayList<FileSystem>();
187
            arr.add(MEMORY);
258
            arr.add(MEMORY);
(-)a/openide.filesystems/test/unit/src/org/openide/filesystems/ContentProviderTest.java (+95 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 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 2011 Sun Microsystems, Inc.
41
 */
42
package org.openide.filesystems;
43
44
import java.net.URL;
45
import java.util.Collection;
46
import java.util.Collections;
47
import java.util.List;
48
import org.netbeans.junit.MockServices;
49
import org.netbeans.junit.NbTestCase;
50
import org.openide.filesystems.Repository.LayersProvider;
51
import org.openide.util.Lookup;
52
53
public class ContentProviderTest extends NbTestCase {
54
    static {
55
        MockServices.setServices(MyProvider.class);
56
    }
57
58
    public ContentProviderTest(String name) {
59
        super(name);
60
    }
61
62
    public void testCheckAFileFromOurLayer() {
63
        FileObject fo = FileUtil.getConfigFile("foo/bar");
64
        assertNotNull("foo/bar is provided", fo);
65
        assertEquals("value is val", "val", fo.getAttribute("x"));
66
    }
67
    
68
    public void testRefreshTheProvider() throws Exception {
69
        MyProvider my = Lookup.getDefault().lookup(MyProvider.class);
70
        assertNotNull("My provider found", my);
71
        
72
        my.clear();
73
        
74
        FileObject fo = FileUtil.getConfigFile("foo/bar");
75
        assertNull("foo/bar is no longer available", fo);
76
        
77
    }
78
    
79
    public static final class MyProvider extends LayersProvider {
80
        private boolean empty;
81
        
82
        @Override
83
        protected void registerLayers(Collection<? super URL> context) {
84
            if (empty) {
85
                return;
86
            }
87
            context.add(ContentProviderTest.class.getResource("test-layer-attribs.xml"));
88
        }
89
90
        final void clear() throws Exception {
91
            empty = true;
92
            refresh();
93
        }
94
    }
95
}

Return to bug 198508