MasterFileSystems is implementation of FileSystem that just delegates to the other FileSystem implementations (LocalFileSystem, VCSFileSystem, ...) and playes the role of arbiter that controls instantiation and life cycle of provided FileObjects.
- FileObjects should have exclusive ownership over a resource. Then just only one FileObject reperesents one java.io.File, then there is ensured, that document opened in editor will be opened only once. This is natural prevention from data lost.
- Simplify access to files. There won't be necessary to mount
individual filesystems, because all sources reachable on your computer
mounted once and automatically.
- It's convenient and more natural if path of FileObject corresponds to path of java.io.File (see current strange nbfs protocol).
FileObjects should have exclusive
ownership over a resource - in more detail
The most important requirement seems to be and motto for all this
effort is: "FileObjects should have exclusive
ownership over a resource" that comes form inceptive issue
#25661: There should not be two DataObject for the same java.io.File.
FileSystems gain to NB development is support for change events. Unknown external changes on resources can't be captured by filesystems and are often source of problems because other APIs that depend on filesystems are not notified about changes,
So, we ever recommend to use FileObjects whenever possible. But as a sort of curiosity if there exists two or more instances of FileObject that address the same resource then all changes via one instance of FileObject means external modification for the others, no synchronization among them, no events. This can lead up to loosing data when there are opened two editors each for one DataObject, both representing the same file which is the problem with the most highest priority.
There is no easy cure for this problem. Here is suggested TODO list:
- classpath can't depend on mounted filesystems in Repository - which is the main cause why to instantiate overlapping FileSystems
- there should exist preferably one reachable instance of
FileSystem for one protocol and also one implementation
of FileSystem should be mostly enough
- prevent users of FileSystem impl. from instantiations of
factories should take responsibility for instantiating) as much
2. There was developed special FileSystem called MasterFileSystem that covers request for just one instance of FileSystem for file protocol which is the most important protocol for NetbeansIDE.
3. Prevent instantiations of FileSystems means more or less, that classes that extend FileSystem shouldn't be publicly accesible. Everybody should be encouraged to request just resource and some factory should provide it. URLMapper coul easily take over the role of factory that should be responsible for instantiating FileSystems instance for requested protocol. Every implementation of FileSystem should provide its own URLMapper except those that are not intended to stay alone and e.g. are expected to be just pluged as delegates into MasterFileSystem.
Use cases for providing implementation of MasterFileSystem SPI:There is no reason for providing more than one implementation of FileSystem related to file protocol. But we have from historical reasons CVS support implemented as FileSystem. MasterFileSystem provides SPI more or less just because of being able to integrate CVS support and to let it plugin into MasterFileSystem.
There is no other known use case at the moment and then there is no intention to create a general purpose API,SPI but rather friend contract (also with respect to performance) between MasterFileSystem and CVS support implementation (as a metter of evolution currently there public packages: org.netbeans.api.masterfs.*, org.netbeans.spi.masterfs.* which should be probably changed for friend contract).
Short design view:
- URLMapper that resolves file protocol and and is responsible for conversion from URL into FileObject and vice versa.
MasterFileSystem is singleton and isn't publicly accesible. FileObjects provided by MasterFilesystem are reachable via:
- Repository - because MasterFileSystem is automaticaly mounted
into Repository (defined as instance in /Mount folder in
mf-layer). MasterFileSystem doesn't keep any persistent
information. But there is intention to remove MasterFileSystem
from Repository as soon as conversion utilities FileUtil.toFile,
FileUtil.fromfile use URLMapper
(just implementation detail). If there was necessary to
visualize FileObjecs from MasterFileSystem then the best
solution could be to get all roots from java.io.File and
then find appropriate FileObjects and present them.
FileObjects are created and cached by using not hard Reference.
Every FileObject from MasterFileSystem has at least one delegate which is kept by hard reference but doesn't keep any children. Delegate is responsible for providing children. Delegate may change during the life of FileObject e.g. delegate from LocalFileSystem can be replaced by delegate from implemenation of some VCS FileSystem. Registered SPI providers can affect which delegate will be used by mounting its own implementation of FileSystem.
FileObjects provided by MasterFileSystem keeps the whole own identity (resource name) and then there is no need to traverse all its parent towards the root to get it.
There is necessary to call refresh to get external changes, fire events and so on.
There is special implementation of root on Windows which has children corresponding to logical drives (A:, C:, D: ...) , has no delegate, there doesn't exist conversion to java.io.File, calling refresh checks logical drives and fires regular events.