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

(-)a/openide.filesystems/src/org/netbeans/modules/openide/filesystems/RecognizeInstanceFiles.java (-16 / +26 lines)
Lines 68-96 Link Here
68
    private static final Logger LOG = Logger.getLogger(RecognizeInstanceFiles.class.getName());
68
    private static final Logger LOG = Logger.getLogger(RecognizeInstanceFiles.class.getName());
69
    
69
    
70
    
70
    
71
    public Lookup create(String path) {
71
    public Lookup create(String path, Lookups.RecursionMode mode) {
72
        return new OverFiles(path);
72
        return new OverFiles(path, mode);
73
    }        
73
    }        
74
    
74
    
75
    
75
    
76
    private static final class OverFiles extends ProxyLookup 
76
    private static final class OverFiles extends ProxyLookup 
77
    implements FileChangeListener {
77
    implements FileChangeListener {
78
        private final String path;
78
        private final String path;
79
        private final Lookups.RecursionMode mode;
79
        private final FileChangeListener weakL;
80
        private final FileChangeListener weakL;
80
        private final AbstractLookup.Content content;
81
        private final AbstractLookup.Content content;
81
        private final AbstractLookup lkp;
82
        private final AbstractLookup lkp;
82
        
83
        
83
        public OverFiles(String path) {
84
        public OverFiles(String path, Lookups.RecursionMode mode) {
84
            this(path, new ArrayList<FOItem>(), new AbstractLookup.Content());
85
            this(path, mode, new ArrayList<FOItem>(), new AbstractLookup.Content());
85
        }
86
        }
86
87
87
        private OverFiles(String path, List<FOItem> items, AbstractLookup.Content cnt) {
88
        private OverFiles(String path, Lookups.RecursionMode mode, List<FOItem> items, AbstractLookup.Content cnt) {
88
            this(path, items, new AbstractLookup(cnt), cnt);
89
            this(path, mode, items, new AbstractLookup(cnt), cnt);
89
        }
90
        }
90
        
91
        
91
        private OverFiles(String path, List<FOItem> items, AbstractLookup lkp, AbstractLookup.Content cnt) {
92
        private OverFiles(String path, Lookups.RecursionMode mode, List<FOItem> items, AbstractLookup lkp, AbstractLookup.Content cnt) {
92
            super(computeDelegates(path, items, lkp));
93
            super(computeDelegates(path, mode, items, lkp));
93
            this.path = path;
94
            this.path = path;
95
            this.mode = mode;
94
            this.lkp = lkp;
96
            this.lkp = lkp;
95
            this.content = cnt;
97
            this.content = cnt;
96
            this.content.setPairs(order(items));
98
            this.content.setPairs(order(items));
Lines 122-143 Link Here
122
                return;
124
                return;
123
            }
125
            }
124
            List<FOItem> items = new ArrayList<FOItem>();
126
            List<FOItem> items = new ArrayList<FOItem>();
125
            Lookup[] delegates = computeDelegates(path, items, lkp);
127
            Lookup[] delegates = computeDelegates(path, mode, items, lkp);
126
            this.content.setPairs(order(items));
128
            this.content.setPairs(order(items));
127
            this.setLookups(delegates);
129
            this.setLookups(delegates);
128
        }
130
        }
129
        
131
        
130
        private static Lookup[] computeDelegates(String p, List<FOItem> items, Lookup lkp) {
132
        private static Lookup[] computeDelegates(String p, Lookups.RecursionMode mode, List<FOItem> items, Lookup lkp) {
131
            FileObject fo = FileUtil.getConfigFile(p);
133
            FileObject fo = FileUtil.getConfigFile(p);
132
            List<Lookup> delegates = new LinkedList<Lookup>();
134
            List<Lookup> delegates = new LinkedList<Lookup>();
133
            delegates.add(lkp);
135
            delegates.add(lkp);
134
            if (fo != null) {
136
            if (fo != null) {
135
                for (FileObject f : fo.getChildren()) {
137
                switch (mode) {
136
                    if (f.isFolder()) {
138
                case FILE:
137
                        delegates.add(new OverFiles(f.getPath()));
139
                    items.add(new FOItem(fo));
138
                    } else {
140
                    break;
139
                        if (f.hasExt("instance") || f.getAttribute("instanceCreate") != null) {
141
                default:
140
                            items.add(new FOItem(f));
142
                    for (FileObject f : fo.getChildren()) {
143
                        if (f.isFolder()) {
144
                            if (mode != Lookups.RecursionMode.NONRECURSIVE_FOLDER) {
145
                                delegates.add(new OverFiles(f.getPath(), mode));
146
                            }
147
                        } else {
148
                            if (f.hasExt("instance") || f.getAttribute("instanceCreate") != null) {
149
                                items.add(new FOItem(f));
150
                            }
141
                        }
151
                        }
142
                    }
152
                    }
143
                }
153
                }
(-)a/openide.filesystems/test/unit/src/org/netbeans/modules/openide/filesystems/RecognizeInstanceFilesTest.java (+21 lines)
Lines 221-224 Link Here
221
221
222
    public static final class Shared extends SharedClassObject {}
222
    public static final class Shared extends SharedClassObject {}
223
223
224
    public void testLoadSingleFile() throws Exception {
225
        String path = "inst/class/" + Inst.class.getName().replace('.', '-') + ".instance";
226
        FileUtil.createData(root, path);
227
        Lookup l = Lookups.forPath(path, Lookups.RecursionMode.FILE);
228
        assertNotNull("Instance created", l.lookup(Inst.class));
229
        assertEquals(1, l.lookupAll(Object.class).size());
230
    }
231
232
    public void testFolderRecursion() throws Exception {
233
        FileUtil.createData(root, "parent/" + Inst.class.getName().replace('.', '-') + ".instance");
234
        FileUtil.createData(root, "parent/child/" + Shared.class.getName().replace('.', '-') + ".instance");
235
        Lookup l = Lookups.forPath("parent", Lookups.RecursionMode.NONRECURSIVE_FOLDER);
236
        assertEquals(1, l.lookupAll(Object.class).size());
237
        l = Lookups.forPath("parent/", Lookups.RecursionMode.NONRECURSIVE_FOLDER);
238
        assertEquals(1, l.lookupAll(Object.class).size());
239
        l = Lookups.forPath("parent", Lookups.RecursionMode.RECURSIVE_FOLDER);
240
        assertEquals(2, l.lookupAll(Object.class).size());
241
        l = Lookups.forPath("parent/", Lookups.RecursionMode.RECURSIVE_FOLDER);
242
        assertEquals(2, l.lookupAll(Object.class).size());
243
    }
244
224
}
245
}
(-)a/openide.util/src/org/netbeans/modules/openide/util/NamedServicesProvider.java (-6 / +12 lines)
Lines 48-68 Link Here
48
48
49
    private static final Map<String,Reference<Lookup>> map = Collections.synchronizedMap(new HashMap<String,Reference<Lookup>>());
49
    private static final Map<String,Reference<Lookup>> map = Collections.synchronizedMap(new HashMap<String,Reference<Lookup>>());
50
    
50
    
51
    public abstract Lookup create(String path);
51
    public abstract Lookup create(String path, Lookups.RecursionMode mode);
52
    
52
    
53
    public static Lookup find(String path) {
53
    public static Lookup find(String path, Lookups.RecursionMode mode) {
54
        if (!path.endsWith("/")) {
54
        if (!path.endsWith("/") && mode != Lookups.RecursionMode.FILE) {
55
            path = path + "/";
55
            path = path + "/";
56
        }
56
        }
57
        
57
        
58
        Reference<Lookup> ref = map.get(path);
58
        String key = mode + "/" + path;
59
        Reference<Lookup> ref = map.get(key);
59
        Lookup lkp = ref == null ? null : ref.get();
60
        Lookup lkp = ref == null ? null : ref.get();
60
        if (lkp != null) {
61
        if (lkp != null) {
61
            return lkp;
62
            return lkp;
62
        }
63
        }
63
        NamedServicesProvider prov = Lookup.getDefault().lookup(NamedServicesProvider.class);
64
        NamedServicesProvider prov = Lookup.getDefault().lookup(NamedServicesProvider.class);
64
        if (prov != null) {
65
        if (prov != null) {
65
            lkp = prov.create(path);
66
            lkp = prov.create(path, mode);
66
        } else {
67
        } else {
67
            ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class);
68
            ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class);
68
            if (l == null) {
69
            if (l == null) {
Lines 71-80 Link Here
71
                    l = NamedServicesProvider.class.getClassLoader();
72
                    l = NamedServicesProvider.class.getClassLoader();
72
                }
73
                }
73
            }
74
            }
75
            switch (mode) {
76
            case RECURSIVE_FOLDER:
77
            case FILE:
78
                throw new UnsupportedOperationException("metaInfServices does not support " + mode);
79
            }
74
            lkp = Lookups.metaInfServices(l, "META-INF/namedservices/" + path);
80
            lkp = Lookups.metaInfServices(l, "META-INF/namedservices/" + path);
75
        }
81
        }
76
        
82
        
77
        map.put(path, new WeakReference<Lookup>(lkp));
83
        map.put(key, new WeakReference<Lookup>(lkp));
78
        return lkp;
84
        return lkp;
79
    }
85
    }
80
    
86
    
(-)a/openide.util/src/org/openide/util/Utilities.java (-1 / +1 lines)
Lines 2823-2829 Link Here
2823
     */
2823
     */
2824
    public static List<? extends Action> actionsForPath(String path) {
2824
    public static List<? extends Action> actionsForPath(String path) {
2825
        List<Action> actions = new ArrayList<Action>();
2825
        List<Action> actions = new ArrayList<Action>();
2826
        for (Lookup.Item<Object> item : Lookups.forPath(path).lookupResult(Object.class).allItems()) {
2826
        for (Lookup.Item<Object> item : Lookups.forPath(path, Lookups.RecursionMode.NONRECURSIVE_FOLDER).lookupResult(Object.class).allItems()) {
2827
            if (Action.class.isAssignableFrom(item.getType())) {
2827
            if (Action.class.isAssignableFrom(item.getType())) {
2828
                Object instance = item.getInstance();
2828
                Object instance = item.getInstance();
2829
                if (instance != null) {
2829
                if (instance != null) {
(-)a/openide.util/src/org/openide/util/lookup/Lookups.java (-1 / +36 lines)
Lines 44-49 Link Here
44
import java.util.Arrays;
44
import java.util.Arrays;
45
import org.netbeans.modules.openide.util.NamedServicesProvider;
45
import org.netbeans.modules.openide.util.NamedServicesProvider;
46
import org.openide.util.Lookup;
46
import org.openide.util.Lookup;
47
import org.openide.util.Parameters;
47
48
48
/**
49
/**
49
 * Static factory methods for creating common lookup implementations.
50
 * Static factory methods for creating common lookup implementations.
Lines 205-210 Link Here
205
     * Please note that these lookups differ in the way they inspect sub-folders.
206
     * Please note that these lookups differ in the way they inspect sub-folders.
206
     * The first lookup just returns instances from the given path, ignoring
207
     * The first lookup just returns instances from the given path, ignoring
207
     * sub-folders, the second one retrieves instances from the whole sub-tree.
208
     * sub-folders, the second one retrieves instances from the whole sub-tree.
209
     * To better control the behavior, use {@link #forPath(String, RecursionMode)}.
208
     * </p>
210
     * </p>
209
     * <p>
211
     * <p>
210
     * Read more about the <a href="../doc-files/api.html#folderlookup">usage of this method</a>.
212
     * Read more about the <a href="../doc-files/api.html#folderlookup">usage of this method</a>.
Lines 214-220 Link Here
214
     * @since 7.9
216
     * @since 7.9
215
     */
217
     */
216
    public static Lookup forPath(String path) {
218
    public static Lookup forPath(String path) {
217
        return NamedServicesProvider.find(path);
219
        return forPath(path, RecursionMode.UNSPECIFIED_FOLDER);
220
    }
221
222
    /**
223
     * Creates a named lookup as in {@link #forPath(String)} but specifying a recursion mode.
224
     * @param path a folder or file path
225
     * @param mode how to deal with folders and files
226
     * @return a lookup associated with the path
227
     * @throws UnsupportedOperationException if mode is not {@link Lookups.RecursionMode#UNSPECIFIED_FOLDER}
228
     *                                       and the active provider cannot handle this recursion mode
229
     * @since XXX
230
     */
231
    public static Lookup forPath(String path, RecursionMode mode) throws UnsupportedOperationException {
232
        Parameters.notNull("path", path);
233
        Parameters.notNull("mode", mode);
234
        return NamedServicesProvider.find(path, mode);
235
    }
236
237
    /**
238
     * Controls how files and folders are interpreted by {@link #forPath(String, RecursionMode)}.
239
     * @since XXX
240
     */
241
    public enum RecursionMode {
242
        /**
243
         * Default mode for compatibility: behavior is dependent on the provider
244
         * (may be like {@link #NONRECURSIVE_FOLDER} or like {@link #RECURSIVE_FOLDER}).
245
         */
246
        UNSPECIFIED_FOLDER,
247
        /** The path is a folder and instances will be searched for in direct children of the folder only. */
248
        NONRECURSIVE_FOLDER,
249
        /** The path is a folder and instances will be searched for in all recursive descendants of the folder. */
250
        RECURSIVE_FOLDER,
251
        /** The path is a single file to be treated as an instance. */
252
        FILE;
218
    }
253
    }
219
    
254
    
220
    /** Creates a lookup that wraps another one and filters out instances
255
    /** Creates a lookup that wraps another one and filters out instances
(-)a/openide.util/test/unit/src/org/openide/util/UtilitiesTest.java (-1 / +1 lines)
Lines 284-290 Link Here
284
284
285
    public void testActionsForPath() throws Exception {
285
    public void testActionsForPath() throws Exception {
286
        MockLookup.setInstances(new NamedServicesProvider() {
286
        MockLookup.setInstances(new NamedServicesProvider() {
287
            public Lookup create(String path) {
287
            public Lookup create(String path, Lookups.RecursionMode _ignore) {
288
                if (!path.equals("stuff/")) {
288
                if (!path.equals("stuff/")) {
289
                    return Lookup.EMPTY;
289
                    return Lookup.EMPTY;
290
                }
290
                }
(-)a/openide.util/test/unit/src/org/openide/util/lookup/PathInLookupTest.java (-1 / +1 lines)
Lines 94-100 Link Here
94
94
95
95
96
        @Override
96
        @Override
97
        public Lookup create(String path) {
97
        public Lookup create(String path, Lookups.RecursionMode _ignore) {
98
            int indx = -1;
98
            int indx = -1;
99
            if (path.equals("MyServices/")) {
99
            if (path.equals("MyServices/")) {
100
                indx = 0;
100
                indx = 0;
(-)a/settings/src/org/netbeans/modules/settings/RecognizeInstanceObjects.java (-7 / +57 lines)
Lines 36-48 Link Here
36
import java.util.Collections;
36
import java.util.Collections;
37
import java.util.logging.Logger;
37
import java.util.logging.Logger;
38
import org.netbeans.modules.openide.util.NamedServicesProvider;
38
import org.netbeans.modules.openide.util.NamedServicesProvider;
39
import org.openide.cookies.InstanceCookie;
39
import org.openide.filesystems.FileObject;
40
import org.openide.filesystems.FileObject;
40
import org.openide.filesystems.FileUtil;
41
import org.openide.filesystems.FileUtil;
41
import org.openide.loaders.DataFolder;
42
import org.openide.loaders.DataFolder;
43
import org.openide.loaders.DataObject;
44
import org.openide.loaders.DataObject.Container;
45
import org.openide.util.Exceptions;
42
import org.openide.util.Lookup;
46
import org.openide.util.Lookup;
43
import org.openide.util.LookupEvent;
47
import org.openide.util.LookupEvent;
44
import org.openide.util.LookupListener;
48
import org.openide.util.LookupListener;
45
import org.openide.util.WeakListeners;
49
import org.openide.util.WeakListeners;
50
import org.openide.util.lookup.AbstractLookup;
51
import org.openide.util.lookup.InstanceContent;
46
import org.openide.util.lookup.Lookups;
52
import org.openide.util.lookup.Lookups;
47
import org.openide.util.lookup.ProxyLookup;
53
import org.openide.util.lookup.ProxyLookup;
48
54
Lines 55-62 Link Here
55
    private static final Logger LOG = Logger.getLogger(RecognizeInstanceObjects.class.getName());
61
    private static final Logger LOG = Logger.getLogger(RecognizeInstanceObjects.class.getName());
56
    
62
    
57
    
63
    
58
    public Lookup create(String path) {
64
    public Lookup create(String path, Lookups.RecursionMode mode) {
59
        return new OverObjects(path);
65
        return new OverObjects(path, mode);
60
    }        
66
    }        
61
    
67
    
62
    
68
    
Lines 65-79 Link Here
65
        private static Lookup.Result<ClassLoader> CL = Lookup.getDefault().lookupResult(ClassLoader.class);
71
        private static Lookup.Result<ClassLoader> CL = Lookup.getDefault().lookupResult(ClassLoader.class);
66
        
72
        
67
        private final String path;
73
        private final String path;
74
        private final Lookups.RecursionMode mode;
68
        
75
        
69
        public OverObjects(String path) {
76
        public OverObjects(String path, Lookups.RecursionMode mode) {
70
            super(delegates(path));
77
            super(delegates(path, mode));
71
            this.path = path;
78
            this.path = path;
79
            this.mode = mode;
72
            CL.addLookupListener(WeakListeners.create(LookupListener.class, this, CL));
80
            CL.addLookupListener(WeakListeners.create(LookupListener.class, this, CL));
73
        }
81
        }
74
        
82
        
75
        @SuppressWarnings("deprecation")
83
        @SuppressWarnings("deprecation")
76
        private static Lookup[] delegates(String path) {
84
        private static Lookup[] delegates(final String path, final Lookups.RecursionMode mode) {
77
            Collection<? extends ClassLoader> allCL = CL.allInstances();
85
            Collection<? extends ClassLoader> allCL = CL.allInstances();
78
            ClassLoader ccl = Thread.currentThread().getContextClassLoader();
86
            ClassLoader ccl = Thread.currentThread().getContextClassLoader();
79
            if (ccl != null) {
87
            if (ccl != null) {
Lines 84-89 Link Here
84
                }
92
                }
85
            }
93
            }
86
            try {
94
            try {
95
                if (mode == Lookups.RecursionMode.FILE) {
96
                    FileObject fo = FileUtil.getConfigFile(path);
97
                    if (fo != null) {
98
                        InstanceCookie cookie = DataObject.find(fo).getLookup().lookup(InstanceCookie.class);
99
                        if (cookie != null) {
100
                            InstanceContent ic = new InstanceContent();
101
                            ic.add(cookie, new InstanceContent.Convertor<InstanceCookie,Object>() {
102
                                public Object convert(InstanceCookie cookie) {
103
                                    try {
104
                                        return cookie.instanceCreate();
105
                                    } catch (Exception x) {
106
                                        Exceptions.printStackTrace(x);
107
                                        return null;
108
                                    }
109
                                }
110
                                public Class<? extends Object> type(InstanceCookie cookie) {
111
                                    try {
112
                                        return cookie.instanceClass();
113
                                    } catch (Exception x) {
114
                                        Exceptions.printStackTrace(x);
115
                                        return Object.class;
116
                                    }
117
                                }
118
                                public String id(InstanceCookie cookie) {
119
                                    return path;
120
                                }
121
                                public String displayName(InstanceCookie cookie) {
122
                                    return path;
123
                                }
124
                            });
125
                            return new Lookup[] {new AbstractLookup(ic)};
126
                        }
127
                    }
128
                    return new Lookup[0];
129
                }
87
                FileObject fo = FileUtil.createFolder(FileUtil.getConfigRoot(), path);
130
                FileObject fo = FileUtil.createFolder(FileUtil.getConfigRoot(), path);
88
                
131
                
89
                String s;
132
                String s;
Lines 94-100 Link Here
94
                }
137
                }
95
                
138
                
96
                org.openide.loaders.FolderLookup l;
139
                org.openide.loaders.FolderLookup l;
97
                l = new org.openide.loaders.FolderLookup(DataFolder.findFolder(fo), s);
140
                l = new org.openide.loaders.FolderLookup(DataFolder.findFolder(fo), s) {
141
                    protected @Override InstanceCookie acceptFolder(DataFolder df) {
142
                        return mode == Lookups.RecursionMode.NONRECURSIVE_FOLDER ? null : super.acceptFolder(df);
143
                    }
144
                    protected @Override InstanceCookie acceptContainer(Container df) {
145
                        return mode == Lookups.RecursionMode.NONRECURSIVE_FOLDER ? null : super.acceptContainer(df);
146
                    }
147
                };
98
                return new Lookup[] { l.getLookup(), Lookups.metaInfServices(allCL.iterator().next(), "META-INF/namedservices/" + path) }; // NOI18N
148
                return new Lookup[] { l.getLookup(), Lookups.metaInfServices(allCL.iterator().next(), "META-INF/namedservices/" + path) }; // NOI18N
99
            } catch (IOException ex) {
149
            } catch (IOException ex) {
100
                return new Lookup[] { Lookups.metaInfServices(allCL.iterator().next(), "META-INF/namedservices/" + path) }; // NOI18N
150
                return new Lookup[] { Lookups.metaInfServices(allCL.iterator().next(), "META-INF/namedservices/" + path) }; // NOI18N
Lines 103-109 Link Here
103
        }
153
        }
104
    
154
    
105
        public void resultChanged(LookupEvent ev) {
155
        public void resultChanged(LookupEvent ev) {
106
            setLookups(delegates(path));
156
            setLookups(delegates(path, mode));
107
        }
157
        }
108
    } // end of OverObjects
158
    } // end of OverObjects
109
}
159
}

Return to bug 169338