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.

Bug 26338 - Allow modules to dynamically add/remove layer content
Summary: Allow modules to dynamically add/remove layer content
Status: RESOLVED FIXED
Alias: None
Product: platform
Classification: Unclassified
Component: Module System (show other bugs)
Version: 3.x
Hardware: All All
: P3 blocker (vote)
Assignee: Jaroslav Tulach
URL:
Keywords: API, API_REVIEW_FAST
: 96404 (view as bug list)
Depends on: 23359 27157 124927
Blocks: 12491 21249 27862 35621 102029 102516 169892
  Show dependency tree
 
Reported: 2002-08-07 13:25 UTC by Jaroslav Tulach
Modified: 2009-08-05 16:26 UTC (History)
18 users (show)

See Also:
Issue Type: ENHANCEMENT
Exception Reporter:


Attachments
Implementation based on using Lookup (5.63 KB, patch)
2004-02-20 15:03 UTC, Jaroslav Tulach
Details | Diff
Yarda's patch applied to NB 5.0. (5.65 KB, patch)
2005-10-21 03:01 UTC, Torbjorn Norbye
Details | Diff
Up to date patch, if there are no comments, I'll integrate on Mar 12th (14.43 KB, patch)
2007-03-05 15:16 UTC, Jaroslav Tulach
Details | Diff
Patch with PN1 and description of the usecase (23.72 KB, patch)
2007-03-07 16:34 UTC, Jaroslav Tulach
Details | Diff
Final patch with test addressing Radim's comments (36.17 KB, patch)
2007-03-13 23:43 UTC, Jaroslav Tulach
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jaroslav Tulach 2002-08-07 13:25:14 UTC
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.
Comment 1 Jesse Glick 2002-08-07 14:49:24 UTC
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.
Comment 2 Jesse Glick 2002-08-07 14:49:59 UTC
Not committing to for 4.0 unless there is a definite need for it.
Comment 3 Vitezslav Stejskal 2002-08-08 00:37:15 UTC
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.
Comment 4 Svata Dedic 2002-08-08 06:59:34 UTC
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 ?
Comment 5 Jaroslav Tulach 2002-08-08 09:05:41 UTC
"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.
Comment 6 Jaroslav Tulach 2002-08-08 09:08:06 UTC
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.
Comment 7 Vitezslav Stejskal 2002-08-08 16:24:27 UTC
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?
Comment 8 Svata Dedic 2002-08-08 16:52:30 UTC
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.
Comment 9 Vitezslav Stejskal 2002-08-08 18:06:29 UTC
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.
Comment 10 Petr Nejedly 2002-08-08 19:12:51 UTC
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.
Comment 11 Jesse Glick 2002-08-09 22:28:16 UTC
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?
Comment 12 Jaroslav Tulach 2002-08-18 09:05:54 UTC
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...
Comment 13 Jesse Glick 2002-08-18 15:51:25 UTC
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.
Comment 14 Jesse Glick 2002-08-19 00:43:25 UTC
A working & public MemoryFileSystem would be handy for modules
inserting layers.
Comment 15 Jesse Glick 2002-08-19 04:37:33 UTC
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".
Comment 16 Vitezslav Stejskal 2002-08-19 14:23:17 UTC
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
Comment 17 Jesse Glick 2002-08-19 17:07:07 UTC
#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.
Comment 18 Vitezslav Stejskal 2002-08-21 13:54:25 UTC
#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
Comment 19 Jesse Glick 2002-08-21 16:52:57 UTC
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.
Comment 20 Vitezslav Stejskal 2002-08-22 18:47:46 UTC
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.
Comment 21 Jesse Glick 2002-08-22 20:04:24 UTC
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.
Comment 22 Jesse Glick 2002-09-11 15:16:35 UTC
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.
Comment 23 mslama 2002-09-12 16:21:56 UTC
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.
Comment 24 Jesse Glick 2003-04-09 20:02:24 UTC
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.).
Comment 25 David Konecny 2003-04-10 08:44:56 UTC
Hmmm... this is interesting idea!
Comment 26 usommerw 2003-04-10 09:41:10 UTC
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>
Comment 27 Petr Nejedly 2003-04-14 15:18:50 UTC
Uta, please file the exception as a separate issue and assign it to
me.
Comment 28 Jaroslav Tulach 2004-02-20 15:03:08 UTC
Created attachment 13549 [details]
Implementation based on using Lookup
Comment 29 Jaroslav Tulach 2004-02-20 15:06:22 UTC
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.
Comment 30 Jesse Glick 2004-02-20 18:44:21 UTC
Patch looks good to me. Planned for D?
Comment 31 Jaroslav Tulach 2004-03-25 16:03:45 UTC
As this might be useful for personalities and needed for promoD, let's
do review.
Comment 32 santhosh 2004-03-31 06:05:33 UTC
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)
Comment 33 Jesse Glick 2004-03-31 06:17:24 UTC
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.
Comment 34 Jaroslav Tulach 2004-04-02 06:44:46 UTC
Ok, review period is over, let's get ready for integration.
Comment 35 Jesse Glick 2004-04-14 17:27:39 UTC
So this isn't going to be integrated after all? Any explanation?
Comment 36 _ ttran 2004-04-15 13:46:58 UTC
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
Comment 37 Manikumar Nagappan 2004-04-17 02:51:51 UTC
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.
Comment 38 Jesse Glick 2004-04-22 20:33:03 UTC
Note: this RFE would be valuable for a JSR 198 implementation.
Comment 39 Nam Nguyen 2005-02-15 06:36:47 UTC
Any chances that this would be in for promoF.  Studio will need this
for a role-based IDE implementation.  Thanks.
Comment 40 Torbjorn Norbye 2005-10-21 03:01:31 UTC
Created attachment 26195 [details]
Yarda's patch applied to NB 5.0.
Comment 41 Torbjorn Norbye 2005-10-21 03:05:41 UTC
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.
Comment 43 Jesse Glick 2007-02-23 22:41:25 UTC
*** Issue 96404 has been marked as a duplicate of this issue. ***
Comment 44 _ tboudreau 2007-02-23 22:59:49 UTC
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).
Comment 45 Jaroslav Tulach 2007-03-05 15:16:26 UTC
Created attachment 39168 [details]
Up to date patch, if there are no comments, I'll integrate on Mar 12th
Comment 46 _ rkubacki 2007-03-05 20:06:13 UTC
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?
Comment 47 Jaroslav Tulach 2007-03-06 08:27:23 UTC
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.
Comment 48 Petr Nejedly 2007-03-06 10:20:36 UTC
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.
Comment 49 Jaroslav Tulach 2007-03-07 16:34:38 UTC
Created attachment 39262 [details]
Patch with PN1 and description of the usecase
Comment 50 Jaroslav Tulach 2007-03-07 16:35:30 UTC
I hope the previous patch answers every asked question except R4.
Comment 51 Jaroslav Tulach 2007-03-13 23:43:26 UTC
Created attachment 39459 [details]
Final patch with test addressing Radim's comments
Comment 52 Jaroslav Tulach 2007-03-13 23:44:11 UTC
If there are no objections I'll apply the patch tomorrow.
Comment 53 Petr Nejedly 2007-03-13 23:54:43 UTC
You don't mean tomorrow morning, do you? Cause I'm certainly not able to
carefully read context diffs this midnight ;-)
Comment 54 Jaroslav Tulach 2007-03-14 14:21:56 UTC
#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
Comment 55 Jesse Glick 2007-03-14 16:10:49 UTC
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));
}
Comment 56 Jesse Glick 2007-03-15 19:02:30 UTC
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.
Comment 57 _ tboudreau 2007-03-21 05:34:09 UTC
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.
Comment 58 Jaroslav Tulach 2007-03-21 10:23:06 UTC
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.
Comment 59 Jesse Glick 2007-03-21 16:44:58 UTC
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.
Comment 60 _ tboudreau 2007-04-02 19:23:11 UTC
Out of curiosity, does this patch mean that everyone needs to *subclass*
MultiFileSystem just so they can get their instance?
Comment 61 Petr Nejedly 2007-04-03 08:09:13 UTC
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.
Comment 62 _ tboudreau 2007-04-03 09:09:50 UTC
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).
Comment 63 Quality Engineering 2008-12-23 14:22:10 UTC
This issue had *1 votes* before move to platform component