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.
Various modules (projects, themes) seem to need to modify the content of system filesystem during runtime. Right now they can do it staticaly by providing module layer, but there is no way to change the layer for example when user switches to black&white theme, etc. I suggest creation of an API that would give modules a way how to provide its own instance of FileSystem that would be inserted into default system file system and its content could be dynamicaly modified during runtime.
I think this could be a nice idea. I would like to see a concrete proposed use case first, though. I'm not sure what you mean by "black & white" etc. Remember that many SPIs for *interpreting* the layer already provide enough flexibility that this enhancement is unnecessary. For example, usersguide provides a file in Mount/ giving either a FileSystem instance, or not, depending on whether the sampledir is really available. It is not necessary to change the static layer; the interpretation of the instance file is dynamic, using methodvalue. This enhancement should probably be paired with a new filesystem impl in the APIs, more or less like FixedFileSystem, but cleaned up a bit. There is not currently a convenient way to make an in-memory FS using the APIs. Ideally a new API would permit some flexibility and safety without subclassing - similar to AbstractLookup + InstanceContent.
Not committing to for 4.0 unless there is a definite need for it.
The use case in projects module is that we need to filter out things like set of templates, main menu actions or toolbars according to the project wich the user is currently working on - the active project. We have the notion of project natures, which define things like project components, default setting values, etc. The idea is that projects natures could also define e.g. the set of appropriate templates, some actions for the main menu, looks applicable for objects in the project, etc. All this stuff defined in project natures of active project would be merged into the SystemFS. When the selection of active project would change the merged stuff would change as well. In other words we would like to have possibility to plug a layer into the SystemFS which would be under the control of projects module and can change its contents as we need.
Vito, what about multiple opened projects ? If templates (from the deafult fs) will be filtered according to Active project contents, won't they disappear from the other projects (with different context and different needs) as well ?
"Black&White" - there used to be a UI proposal to have preset settings for different environment/people. This should influence the colors in editor, explorer, size of windows, etc. The suggested implementation was to provide each of the presets as a layer for a system file system and activate just one at a time. The here in described functionality would creation of such module.
Simplest implementation propsal: Add to manifest new entry: OpenIDE-Module-Dynamic-Layer: org/nb/themodule/ImplOfOwnFS.class and if found, add it to the system filesystem as one layer.
Svato, the list of templates is accessible from nodes, thus before the list is displayed the node is selected which operation will change the layer (if the node belongs to diferent project than that previously activated). Is there any problem in this scenario?
Your proposal is to change shared data (contents of the default fs) in favour of one of its clients (project node) because of an operation performed specifically in that client's context (project-aware action). That is almost always bad, since there are other clients working with the templates folder, that will be affected by whatever was the project used recently. E.g. some module - not your nodes - will browse through templates as DataObjects. It will never see a consistent state, nor all available templates - given that the session is project neutral, it seems strange. BTW what about Tools | Options | Source Management | Templates ? I don't think it will be much useful if the contents changes every time you move focus from one project to another.
Right, but either the module doesn't care about projects at all and then it should be happy with default (generic) set of templates or it cares about the project and then it has to search for templates in context of some project anyway. Looking through the SystemFS it will get the context of project where user works, otherwise (if the module knows the project context) it can search for templates on ProjectFileSystem.
If I understand it correctly, you (projects) are about to change the content of the system FS and/or global UI (e.g. top-level menus) when user e.g. click on a different node. I *strongly disagree* with this kind of abuse of the system FS and with changing global UI on such event, not yet talking about the performance impact it will have.
OK, a few things: - I don't follow all of the details of your discussion of how to change project natures, and I doubt they are all relevant here. dev@projects.netbeans.org is the right place. I mainly want to make sure that there is consensus that the projects module should be able to install its own filesystem. - Re. Petr's concern about changing the SFS when a node is clicked: definitely, this would be quite unreasonable for performance. It is fine to change the SFS when the user explicitly opens/closes a project, etc. - The example re. Black & White theme could be implemented by adding layers, but it need not be. A more compelling example IMHO is editor keybinding presets. - Re. Yarda's suggested syntax: doesn't look bad, could work. It does force you to create a FileSystem subclass, and leaves some ambiguity re. where module-supplied layers go relative to core ones. Another possibility: 0. No manifest syntax change required. 1. Define some special folder in the SFS, say Layers/, expected to contain instances of FileSystem (or FileSystem[] maybe, or subfolders with more instances, etc.). All such instances found there will be merged into the SFS. 2. The core will define three files (?), representing $userdir/system/, $nbhome/system/, and the result of merging together module XML layers (which will be cached BTW). Modules such a projects can define additional files. 3. Subfolders are permitted and are defined to have behavior similar to creating a new MultiFileSystem as far as masking goes, i.e. a *_hidden file can only mask a file in the same level, and will not be propagated to the higher level. 4. Order is significant: earlier filesystems can mask files in later filesystems. 5. The behavior is undefined in case a layer defines a mask which would hide its own instance file from the SFS, or the list of filesystems to merge is otherwise ambiguous due to recursion: in practice this would set up a loop if it happened, but I can't see any usage model in which it would happen. Maybe the situation can be reliably detected at runtime, maybe not. 6. The SystemFileSystem.layer file attr is deprecated and replaced with a new attr (just "layer"?) which would point to the resource name of the filesystem instance file on which changes to a file ought to be stored. Does the above proposal sound intuitive and/or implementable?
Ad. the /Layer proposal. At first sight it looks a bit recursive and hard to implement, but at the second it has a beauty inside, especially by outsourcing the $nbuser/system and $nbhome/system out of the "kernel" core implementation allowing easy branding of such things. I like it. My only worry is that the bootstrap will not be easy. First of all we have to initialize the layers of modules in lib/ directory (getClass().getClassLoader().getResources ("META-INF/MANIFEST.MF")), then read content of /Layers folder, change the SFS to include $nbuser/system $nbhome/system (provided by core-ui), thus the content of Modules directory changes, initialize new modules (also means change SFS), check if there was a change in /Layers folder, etc...
Right, I am worried that the bootstrapping might be intractably hard. Especially considering that the merge module layers is supposed to be cached, meaning it has to be read in all at once, etc. Possibly simplifying modification: the system will indeed create instance files for "built-in" layers, but their positions will be fixed, and they will not really be queried for instances: i.e. you cannot brand them out or mess with them in any way, as the core would create and merge their instances directly. However you could still order other filesystems relative to them. Since modules are not generally permitted to interfere with objects installed by other modules (incl. the core), the fact that in this case it will really not work, should not matter much.
A working & public MemoryFileSystem would be handy for modules inserting layers.
I am trying out a possible impl of Yarda's initial proposal on the branch dynlayers_26338 (in core & projects modules). I have no idea if I can actually implement it stably because: 1. FileStateManager, used to move files between layers (project + session + installation), may work strangely. 2. The projects module might not be able to share file locks with LocalFileSystemEx any more, unless some more hacks are put in place. 3. Worst, SessionManager previously notified clients of project open/close events using a listener scheme. I just commented out this code because it cannot work (as far as I can tell) using the proposed changes: the projects module will have one delegate layer in the SFS and this will change internally when a project is switched. The core will know nothing about it. Various pieces of code in core were listening to SessionManager - I don't understand why, or what this accomplished that regular FileChangeListener's would not accomplish. Will probably have to pass this off to Vita to finish implementation if I can get a prototype running, since he seems to have written most of the code that I cannot figure out how to modify. Re. my idea for finding layers from a Layers/ folder - I think bootstrapping would be implementable but I fear that the complexity of the threading during an update would make this a huge source of bugs, since there is really no way to predict when a FolderInstance might refresh itself other than "later".
Random things which I remember: 1. WindowSystem guys had hard time to stabilize WS during project switch, dozens of events from DFS, asynchronous processing in FolderInstance, etc. What they realy need is to throw away all windows from old project, let the new project to be turned on and load windows from that new project. 2. FileStateManager (and perhaps OptionsAction too) listen on SessionManager in order to be notified when project layer dismiss (or appears again), e.g. when projects module is disbaled/enabled. 3. Some parts of system need to be "frozen" when filesystems are being mounted after project switch (e.g. WS needs to wait for all filesystems to be mounted, otherwise some editor windows might be accidentaly closed) 4. We (projects) will not implement projects layer in new projects infrastructure anymore. Then the layer switching and FileStateManager, etc. will get obsolete and could be removed IMO
#1 sounds like the really evil part. The window system as I understand it is not sufficiently stable to actually work correctly when layers are switched from under it. Without some API to signal to the window system that changes in files under Windows/ are about to begin, and then that they have ended, it will be permanently unstable. We were able to hack around it only because we happened to be doing the layer switching in core. Now the switching may happen in any module, which knows nothing about the window system. IMHO we need to really fix the threading & atomicity stuff here, or else we have to introduce a new *public API* similar to the old SessionManager. #2: this is no longer meaningful, i.e. there is always a ModuleMixedFileSystem, with 0 or more modules contributing. Can this code be deleted? Does it still serve some purpose? #3: yuck, same comments as above for #1. #4: well, you have *some* layers, right? I was planning to patch PSupport.java in the branch to do the equivalent of what it does now, but using the mixin filesystem instead of calling into SessionManager. You could replace this with something more sophisticated whenever you wanted.
#4: OK, I will use it if neccessary, but I think that we will not have any project's layer in new infrastructure. I used to plan it, but I accept pnejedly's comments that it would have negative performance impact. BTW, we talked off-line with Yarda, who wishes to change existing (3.4) projects module to 'Session Manager'. Then it would definitely use this new mechanism for module pluggable layers. But I am still not sure how the Tools/Options would implement moving between layers if it knows nothing about the structure of FileSystem plugged by module
Re. project layers: so you will have *no* project-supplied layer in SFS in 4.0, or you do not need to change it dynamically? Re. session manager module: I think this is a nice idea. But I agree that there is no obvious way how it could move files between layers when it does not where or what the layers are. For the time being I am not working actively on this issue because: 1. Problems with the window system sound too hard to solve without a lot of help from win sys developers, since the win sys will not react in the expected way to simple file events, and there is no clear definition of what a "project switch" means if this issue is implemented. 2. The session manager would probably not work well with the manifest tag, I think. The Layers/*.instance style might be friendlier for a session manager, but this would require a lot more design work, and I don't know if it can be implemented at all when the current state of threading in Filesystems & Datasystems is so chaotic and unreliable. 3. It sounds projects developers *don't* need this RFE after all, so priority should be lower.
If we would use project layer we need to change its contents according to the *current* project, which potentialy means frequent changes. pnejedly refused that idea, without it the whole concept of projects layer makes no sense from new projects architecture point of view. Thus I've abandon this idea, feel free to lower the prio.
OK. I had assumed that the project switch would be a user-initiated action like it is now, even if there could be >1 project layer open at once. But if the switch would be after e.g. a change in node selection, this would be unreasonable.
Issue #27157, something to do with improving window manager responsiveness to layer changes outside the context of a project switch, would probably make this RFE easier - though I suspect further window system fixes would still be needed, since that patch includes hardcoded references to the name of the projects module, etc. etc. Unfortunately I don't think the FS API gives the window system any way of just listening for "batches" of changes - if it did, the WS could be (more) independent of the session manager, with logic something like: 1. Wait for a batch of FS/DS changes under Windows/. 2. (Optional) If just one or two changes, compute effect on existing windowing components and apply. 3. If a lot, throw out existing win sys and recompute. There are "atomic actions" in the FS API (misnamed - they are not really atomic at all, they just delay firing) but this does not present all changes together in one bundle. DS API does not seem to have anything like this at all. If threading in these APIs were predictable, clients could manually assemble batches by coalescing all changes posted during the last write mutex interval; with the current architecture this is not practical. So any kind of session manager has to have a way of explicitly telling the window system: "stop now, I am about to do things.... doing them..... done, update windows now". For now, the only such communication is a project switch as controlled by SessionManager.
For winsys the same problem arises when module (contributing to winsys layer) is enabled/disabled. In addition we cannot save winsys even partially when layer content is changed. (unfortunately it is not one way street - we must also sometimes save changes made by user - not only to react on changes in FS/DS) So besides knowing that there is some change in layer so winsys should stop listening till layer change is finished we would need also some mechanism to detect that we cannot save winsys when module is disabled/enabled. It is different from project (session) switch where we save winsys explicitely before old project layer is removed.
If supported, should be part of the Registry system - e.g. ---%<---mymodule.jar!/META-INF/services/org.netbeans.spi.registry.RootContextFactory org.netbeans.modules.mymodule.ExtraTheme ---%<--- where ExtraTheme implements RootContextFactory to create a read-only, non-resettable root context adding in some dynamically computed stuff (switchable theme, etc.).
Hmmm... this is interesting idea!
Hi, would be nice to have the following (stabilized) stuff in openide... for some legacy reasons we have our own XML vocabulary to define actions and menus. When attaching one part of our stuff, we read the own definitions from a database. To wrap this for netbeans we are creating menu definitions compatible to the netbeans XML layer vocabulary and place them in temporary files directly in the netbeans user folder. To add the stuff, we use the following code (it is not part of openide, sorry, but we've proved this to be the most elegant way): host = ModuleLayeredFileSystem.getUserModuleLayer(); Collection urls = new ArrayList(); urls.add(new URL(<tmp_file_name>)); synchronized (host){ host.addURLs(urls); } and for removing we call analogously: synchronized (host){ host.removeURLs(urls); } We have to deal with different sets of definitions within one netbeans module. In generally it works well, but we got sometimes exceptions of the type below, in case there are overlapping definitions for menus in a short sequence of calls removeURLs() and addURLs(). It seams to be a synchronization problem. Is there any hope to synchronize such calls????!!!!!!!! Thanks in advance, Uta Sommerweiß Annotation: Exception occurred in Request Processorjava.lang.ArrayIndexOutOfBoundsException: No such child: 6 at java.awt.Container.getComponent(Container.java:237) at javax.swing.JMenuBar.getComponentAtIndex (JMenuBar.java:233) at javax.swing.JMenuBar.getMenu(JMenuBar.java:188) at javax.swing.plaf.basic.BasicMenuBarUI$ChangeHandler.stateCh anged(BasicMenuBa rUI.java:179) at javax.swing.DefaultButtonModel.fireStateChanged (DefaultButtonModel.java:361) at javax.swing.DefaultButtonModel.setMnemonic (DefaultButtonModel.java:295) at javax.swing.AbstractButton.setMnemonic (AbstractButton.java:1370) at javax.swing.AbstractButton.setMnemonic (AbstractButton.java:1391) at org.openide.awt.Actions.setMenuText(Actions.java:165) at org.openide.awt.MenuBar$LazyMenu.updateProps (MenuBar.java:287) at org.openide.awt.MenuBar$LazyMenu.propertyChange (MenuBar.java:299) at org.openide.util.WeakListener$PropertyChange.propertyChange (WeakListener.jav a:485) at org.openide.nodes.Node.fireOwnPropertyChange (Node.java:937) at org.openide.nodes.Node.fireDisplayNameChange (Node.java:797) at org.openide.loaders.DataNode.fireChangeAccess (DataNode.java:484) at org.openide.loaders.DataNode$PropL.run (DataNode.java:635) at org.openide.util.Task.run(Task.java:136) at org.openide.util.RequestProcessor$Task.run (RequestProcessor.java:328)[catch] at org.openide.util.RequestProcessor$Processor.run (RequestProcessor.java:667) Example for generated XML: <?xml version="1.0"?> <filesystem> <folder name="Menu"> <folder name="View"> <file name="SeparatorRo20.instance"> <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/> </file> <attr boolvalue="true" name="de-rochade-rap-applications-ap-actions- DisposeReportAction.instance/Se paratorRo20.instance"/> <file name="de-rochade-rap-applications-ap-actions- ExpandAction.instance"/> <attr boolvalue="true" name="SeparatorRo20.instance/de-rochade-rap-applications- ap-actions-ExpandAc tion.instance"/> <file name="de-rochade-rap-applications-ap-actions- CollapseAction.instance"/> <attr boolvalue="true" name="de-rochade-rap-applications-ap-actions- ExpandAction.instance/de-rochad e-rap-applications-ap-actions-CollapseAction.instance"/> <file name="SeparatorRo21.instance"> <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/> </file> <attr boolvalue="true" name="de-rochade-rap-applications-ap-actions- CollapseAction.instance/Separat orRo21.instance"/> <file name="de-rochade-rap-applications-ap-actions- ViewInDiagramAction.instance"/> <attr boolvalue="true" name="SeparatorRo21.instance/de-rochade-rap-applications- ap-actions-ViewInDi agramAction.instance"/> <file name="de-rochade-rap-applications-ap-actions- ViewInTableAction.instance"/> <attr boolvalue="true" name="de-rochade-rap-applications-ap-actions- ViewInDiagramAction.instance/de -rochade-rap-applications-ap-actions- ViewInTableAction.instance"/> <file name="de-rochade-rap-applications-ap-actions- ViewInTreeAction.instance"/> <attr boolvalue="true" name="de-rochade-rap-applications-ap-actions- ViewInTableAction.instance/de-r ochade-rap-applications-ap-actions- ViewInTreeAction.instance"/> <file name="SeparatorRo22.instance"> <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/> </file> <attr boolvalue="true" name="de-rochade-rap-applications-ap-actions- ViewInTreeAction.instance/Separ atorRo22.instance"/> </folder> <attr name="OpenIDE-Folder-Order" stringvalue="View"/> </folder> <folder name="Shortcuts"/> <folder name="Actions"> <folder name="Rochade"> <file name="de-rochade-rap-applications-ap-actions- ExpandAction.instance"/> <file name="de-rochade-rap-applications-ap-actions- CollapseAction.instance"/> <file name="de-rochade-rap-applications-ap-actions- ViewInDiagramAction.instance"/> <file name="de-rochade-rap-applications-ap-actions- ViewInTableAction.instance"/> <file name="de-rochade-rap-applications-ap-actions- ViewInTreeAction.instance"/> </folder> </folder> </filesystem>
Uta, please file the exception as a separate issue and assign it to me.
Created attachment 13549 [details] Implementation based on using Lookup
If the previous patch is applied any module can contribute its own filesystem as a layer of SystemFileSystem. In order to plug for example org.nb.themes.ThemeFileSystem one has to create file: META-INF/services/org.openide.filesystems.FileSystem containing one line: org.nb.themes.ThemeFileSystem in module JAR file.
Patch looks good to me. Planned for D?
As this might be useful for personalities and needed for promoD, let's do review.
I want to hide irrelevant menu's and toolbars depending on the file user is currently editing. for example, if user is currently editing and xml file, the Debug and Build related menus and toolbars(which don't make sense) are not shown. As soon as user switches to java file, Debug and Build related menus and toolbars should appear. After this bug fix, I should be able to achieve this functionality (as Jesse Glick suggested)
Santhosh - it should work, but be aware that what you are proposing would perform poorly. Every time the user switched editor tabs, the menu and toolbars might switch; this is considered a relatively heavyweight operation appropriate to major events like enabling or disabling modules or making explicit configuration changes, but which would quickly grow annoying in everyday use. You can try it, of course, and maybe it will be acceptable for you in a custom application - we would not accept this in the NB IDE.
Ok, review period is over, let's get ready for integration.
So this isn't going to be integrated after all? Any explanation?
i am blocking it. The main reason is the performance impact is still not clear and I see no plan to use in promo-d. We don't want to introduce an API without usage and regret it later
I just observed one issue with this patch, where my filesystem registered through Lookup was added to the Default FileSystem multiple times. I had to fix SystemFileSystem.computeLayers() method so that it does not add any FileSystem that already exists. I am not sure if this is a general problem because i am trying this on Netbeans 35 and also i have other patches that are my own. But i just wanted to let you know in case it is a general issue. Here is the snippet for core.projects.SystemFileSystem.computeLayers () method: private synchronized static FileSystem[] computeLayers () { FileSystem[] fromLookup = (FileSystem[]) result.allInstances ().toArray (new FileSystem[0]); //patch:begin //Details: the registered FileSystem gets added second time even though //it already exists. This patch checks for non- existant file systems and //adds only those. //if (fromLookup.length > 0) { // ArrayList arr = new ArrayList (layers.length + fromLookup.length); // arr.addAll (Arrays.asList (layers)); // arr.addAll (Arrays.asList (fromLookup)); //REPLACED THE ABOVE COMMENTED CODE WITH:- List newLookupEntries = new ArrayList(); List list = Arrays.asList(layers); for (int i=0; i<fromLookup.length; i++){ if (!list.contains(fromLookup[i])) { newLookupEntries.add(fromLookup[i]); } } if (newLookupEntries.size() > 0) { ArrayList arr = new ArrayList (layers.length + newLookupEntries.size()); arr.addAll (Arrays.asList (layers)); arr.addAll (newLookupEntries); //patch:end return (FileSystem[])arr.toArray (new FileSystem[0]); } return layers; } PS: I don't have the Netbeans35 build env at presentt to be able to submit patch / unit test. If i get to setup one i'll certainly submit a patch as suggested by Jesse Glick.
Note: this RFE would be valuable for a JSR 198 implementation.
Any chances that this would be in for promoF. Studio will need this for a role-based IDE implementation. Thanks.
Created attachment 26195 [details] Yarda's patch applied to NB 5.0.
I have a use case for this. I'm building a simple API for some IDE services. The service-side of my API then implements these APIs by using a wide variety of existing NetBeans APIs. However, many of these NetBeans APIs rely on having services registered in the layer. That means that my code needs to "provide" files in the system file system (consumed by the existing NetBeans APIs), and these must be computed on the fly based on services registered for the new API. For one concrete example, I need to register files into Editors/mimetype/mimesubtype based on registered services to my API, such that the editor will find my services.
some related piece of code used by old projects http://core.netbeans.org/source/browse/core/startup/src/org/netbeans/core/startup/layers/SessionManager.java?r1=1.6&r2=1.7
*** Issue 96404 has been marked as a duplicate of this issue. ***
See also duplicate issue 96404 with a very similar patch (the only difference being the ability to dynamically enable/disable the filesystem provided and have it appear/disappear, which may be useful for managing things like authenticated vs. not authenticated UI state).
Created attachment 39168 [details] Up to date patch, if there are no comments, I'll integrate on Mar 12th
Few questions: R1 - why global lookup? See for example Jesse's idea in comment 12. R2 - what is performance impact? does it mean that once we initialize global lookup during startup we will update delegates of SFS (and maybe fire various FS changes maybe chained by lookup changes ... )? What's the cost if some changes this during runtime (see Tim's usecase to update UI to reflect result of some user's action like login to main server)? R3 - (related to R2) do we plan to use it in IDE? R4 - exact semantic of patch is missing. How are all the layers ordered?
Re. R1 - META-INF/services is JDK standard. I do not know what is "comment 12", but I have no problems using META-INF/services, I only was not absolutely sure whether searching directly for org.openide.filesystems.FileSystem is the best, whether there should not be some other intermediate interface, but functionality would stay the same, so I decided for simplicity. Re. R2 - I have written a module that registers file change listener in its ModuleInstall and also provides a filesystem over user home directory. On startup, there is no file event caught by the listener - e.g. no slowdown due to event storms. Re. R3 - Not for stable IDE modules in 6.0 Re. R4 - I'll write a test to verify what layer masks what.
PN1: Well, the listening pattern should be: addListener(whichCallsUpdate); update(); not the other way around, as it would be prone to race conditions otherwise. You have it potentially wrong twice in the patch.
Created attachment 39262 [details] Patch with PN1 and description of the usecase
I hope the previous patch answers every asked question except R4.
Created attachment 39459 [details] Final patch with test addressing Radim's comments
If there are no objections I'll apply the patch tomorrow.
You don't mean tomorrow morning, do you? Cause I'm certainly not able to carefully read context diffs this midnight ;-)
#26338: Ability to influence content of sfs via lookup" Checking in core/startup/src/org/netbeans/core/startup/layers/SystemFileSystem.java; /shared/data/ccvs/repository/core/startup/src/org/netbeans/core/startup/layers/SystemFileSystem.java,v <-- SystemFileSystem.java new revision: 1.9; previous revision: 1.8 done RCS file: /shared/data/ccvs/repository/core/startup/test/unit/src/org/netbeans/core/startup/layers/SystemFileSystemTest.java,v done Checking in core/startup/test/unit/src/org/netbeans/core/startup/layers/SystemFileSystemTest.java; /shared/data/ccvs/repository/core/startup/test/unit/src/org/netbeans/core/startup/layers/SystemFileSystemTest.java,v <-- SystemFileSystemTest.java initial revision: 1.1 done Checking in openide/arch/arch-openide-filesystems.xml; /shared/data/ccvs/repository/openide/arch/arch-openide-filesystems.xml,v <-- arch-openide-filesystems.xml new revision: 1.26; previous revision: 1.25 done Checking in openide/fs/apichanges.xml; /shared/data/ccvs/repository/openide/fs/apichanges.xml,v <-- apichanges.xml new revision: 1.12; previous revision: 1.11 done Checking in openide/fs/manifest.mf; /shared/data/ccvs/repository/openide/fs/manifest.mf,v <-- manifest.mf new revision: 1.9; previous revision: 1.8 done Checking in openide/fs/src/org/openide/filesystems/ExternalUtil.java; /shared/data/ccvs/repository/openide/fs/src/org/openide/filesystems/ExternalUtil.java,v <-- ExternalUtil.java new revision: 1.8; previous revision: 1.7 done RCS file: /shared/data/ccvs/repository/openide/fs/test/unit/src/org/openide/filesystems/RepositoryTest.java,v done Checking in openide/fs/test/unit/src/org/openide/filesystems/RepositoryTest.java; /shared/data/ccvs/repository/openide/fs/test/unit/src/org/openide/filesystems/RepositoryTest.java,v <-- RepositoryTest.java initial revision: 1.1
Why does the ExternalUtil.MainFS constructor call resultChanged(null)? Its super constructor already gets computeDelegates(). The example given in arch.xml looks wrong to me. (Did you actually try it?) It assumes that the same instance of LoginFileSystem will be returned both from Lookup.gD().l(FS.class) and from Lookup.gD().l(LoginFS.class), which I don't think is guaranteed. I would recommend: 1. Register only META-INF/services/org.openide.filesystems.FileSystem, not META-INF/services/your.module.LoginFileSystem. 2. Change code to read private static LoginFileSystem INSTANCE; public LoginFileSystem() { INSTANCE = this; } public static void assignURL(URL u) { INSTANCE.setDelegates(new XMLFileSystem(u)); }
I removed the extra call to resultChanged(null). I simplified the example given in the use cases section. The original style did work (although it did not compile as written), but the revised example is shorter and probably simpler to understand.
The last version of Jarda's patch didn't address enabling/disabling the whole contributed filesystem at once, which almost everyone is going to need (the patch attached to issue 96404 did cover this case simply by adding an intervening provider interface with an enabled property). Would like to see that as I think almost everyone is going to need it (generally people want this in order to add/remove large numbers of things quickly), and will probably want to use XMLFileSystem to define dynamic content. Any chance this can be revisited? It is possible to do it with existing code, e.g. I create a MultiFileSystem, and when I want to enable things I can add an XMLFileSystem to it. But it does mean an extra layer of delegation and the system filesystem needs to be fast.
This is your usecase: http://www.netbeans.org/download/dev/javadoc/usecases.html#usecase-File System API If you have some measurements showing it is not efficient, provide them, please.
http://www.netbeans.org/download/dev/javadoc/usecases.html#usecase-File%20System%20API that is. I tried this use case (actually edited it a bit from my experiments) and it seemed to work fine. I didn't notice any overhead, but I didn't try to profile it either.
Out of curiosity, does this patch mean that everyone needs to *subclass* MultiFileSystem just so they can get their instance?
Yes, or some other filesystem for that matter. One class overhead for rarely used feature is not a problem. I would see much bigger problem if few such pluggable filesystem registrations sneaked into NB distro.
I suppose either way there will be one more class. I think it would be slightly more intuitive to have something like: public interface FilesystemProvider { public FileSystem getFilesystem(); ...enablement/listing logic } than to make someone understand what is MultiFileSystem, etc. (e.g. what I attached to 96404).
This issue had *1 votes* before move to platform component