Design of the Filesystems Extension
$Revision: 1.2 $
Changes: available in
CVS
Abstract:
Lookup for each file object is the central part of the Filesystems Extension API.
This lookup is constructed with help of MIME type of the individual file.
Additional functionality (file visibility, adding copy, move enhancers)
is achieved by using this lookup.
MimeType usage
The extensibility by other modules will be based on
mime type (For more info see Chapter 5 in
RFC 2045).
By reusing the
installation layer we can share all its benefits, for example
ordering of files in folder.
Special care has to be paid to XML mimetypes. Because the format
used for different purposes it is heavily overloaded and thus very likely shared
between a lot of different modules (Ant, XML, settings and many more).
There is a RFC 3023 to use text/ant+xml
to describe that an document
is Ant one and also XML. In order to support this we shall
check
FSExtension/Mime/text/ant, FSExtension/Mime/text/xml, FSExtension/Mime/text and
FSExtension/Mime/.
Lookup for each FileObject
The module will provide a separate lookup for each file object. The proposed
API for getting at one is this
Lookup l = FSExtension.getDefault().getLookup(fileObject);
The lookup will be the main extension point for the module authors
to attach functionality to common file operations (copy, move, delete).
The attachable behaviour will be described
by a set of interfaces in the SPI (e.g. Copy, Move, Delete). But of course
any object can be attached to any file object so it will also be
a way for modules to communicate with each other.
This lookup will be based on the MIME type of the file object. The MIME types
provides us a hierarchical name space so the content of the lookup
for text/plain will be constructed from contents of the following
folders: "FSExtension/Lookup", "FSExtension/Lookup/text",
"FSExtension/Lookup/text/plain". As you can see the FSExtension/Lookup folder
on the system file system will be the root of the MIME type heirarchy.
The implementaion accesses the system file system using Registry API.
<TBD comment="this might be out of date. needs to be rethink in context of Convertor API.">
As the module author would register the content of the lookup in layer and
the objects in the lookup are bound to individual file objects there has
to be a way to pass the file object reference to the module author's supplied
objects. I have solved this by introducing LookupContentFactory interface and
forcing the module authors to register factories producing either
the resulting objects or lookups.
In order not to load the module classes before needed we can supply a wrapper
factory - so you would register your factory in layer using method
value (calling our method) and the wrapper would not load your class
unless really needed:
<file name="Foo.instance">
<attr name="instanceCreate"
methodvalue="org.netbeans.spi.fse.LookupContentFactoryManager.create"/>
<attr name="factoryClass" stringvalue="org.netbeans.modules.foo.FooFactory"/>
<attr name="implements" stringvalue="org.netbeans.spi.foo.FooInterface"/>
</file>
LookupContentFactoryManager.create produces the wrapper for your factory.
FooFactory has to implement LookupContentFactory and the attribute implements
is telling you what does the object returned by the factory implement.
If the factory returns lookup the lookup will be a part of the resulting
lookup from the file object. But the lookup will be asked only for objects
from the implements list - this is performance optimalization provided
by the wrapper factory.
</TBD>
Copy, delete, move
I propose an interface Copy containing methods canCopy, beforeCopy,
afterCopy and cancelCopy (org.netbeans.spi.ds.Copy). Someone may
call it a specialized listener.
If a module would like to attach some behaviour to the copy operation the
author would implement this interface and also create and
register factory producing his/her objects. When we do copy on
a file object its lookup contains all such "enhancers". They
will be called (all). Please check org.netbeans.api.ds.FSExtension.copy(...).
So in essence I allow for listenning and doing additional actions
when something is copied, moved, deleted etc. Please see bellow\
for threading of these operations.
Creating objects from template should be handled by a special
module which can use the FSExtension but FSExtension can know
nothing about this module.
Hiding files (in the presentation layer)
<TBD comment="this needs to be rethink. presentation layer should be completely separated from FS Extension"
>
The old data system provided grouping of files. After reading Holger's argument
I agree that what we need is not really grouping but a way to hide certain
types of files in the explorer. The people who really mean grouping won't suffer
since the combination of hiding and attaching functinality to files the
module authors should be given enough power to implement what they need.
To produce a default view there will be an interface in the SPI
(for now it is called DefaultFolderView - better name anyone?) with just one
method - isVisible or similar. Modules would be able to register instances
of this to the file object lookup - that could provide the deafult look
enough information whether the file should be visible or not. Please note
that that the hierarchical MIME type space is searched from the most
specific to more general so you would be able to override the visibility
(e.g. xml module would say that xml files are visible and the form module
would like to hide special kind of xml files).
Also please consider this functionality only for some default look (see bellow)
which might not be needed in the IDE where the projects module will provide
its own look with its own mechanism of determing what should be visible and what
hidden.
</TBD>
Threading
<TBD comment="needs to be rethink in context of threading redesign"
>
In the Jarda's design he proposed
a special thread for modification of the state of the system.
I can see two ways for dealing with threads:
Use Jarda's proposal
The one thread system from branch ds_16389 can be reused in the
FSExtension implementation.
Ignore threading
This is current state of the prototype. It does not create any new threads,
does no synchronization, calls everything synchronously. It might
prove to be slow but all the operations as for now are invoked in
a special thread (ModuleActions thread)
so they do not block the AWT thread.
Please check also open issues in the main document.
</TBD>
Default looks based on FileObjects
<TBD comment="needs to be rethink. separate visualisation to separate docs."
>
The fselooks module provides looks for file objects that
- utilize the hiding mechanism
- provide places for extensions (adding actions etc.)
- provide places for specifying alternative looks
Adding actions is achieved by using special kind of composite looks with well
defined set of places where to look for the looks --- based on
the MIME type of the file.
Before applying the default composite there would be (another) namespace
allowing to register alternative looks for the MIME type.
An alternative to looks
If the looks are not finished in time for the Filesystems Extension
following approach can be taken to provide some of the required
functionality.
A module can provide a node in the lookup for a given MIME type.
This node can be used to display the file - this might resemble
getNodeDelegate method. To achieve the extensibility of actions
of such nodes I propose a simple abstract class extending AbstractNode
that would fetch the actions using JNDI (e.g. pass the JNDI name
in constructor (as String)). If the module author wants to make
the list of actions of his node extensible this special class
can be used as superclass of the node passed to the lookup.
Changing the node for a given MIME type would require reorder
of the content of a folder on the system file system. A special
node for folder would be required --- with the extensibility described
above but with otherwise fixed functionality.
The disatvantage of this mechanism is lack of possibility for
other modules to change children of nodes. The advantage
of this proposal is its great simplicity. Looks provide much
more functionality and extensibility so they are still
a preferred way to go.
</TBD>