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 34541

Summary: Provide an EditorSupport class for FileObjects, which does not rely on DataObjects
Product: platform Reporter: Petr Jiricka <pjiricka>
Component: TextAssignee: issues@editor <issues>
Status: NEW ---    
Severity: blocker CC: issues, jglick, jtulach, mpetras, raccah
Priority: P3 Keywords: API, ARCH
Version: 3.x   
Hardware: All   
OS: All   
Issue Type: ENHANCEMENT Exception Reporter:
Attachments: Zip file containing the new files for DataObject-less editing

Description Petr Jiricka 2003-06-23 18:26:33 UTC
Currently, if a module wants to provide an editing 
capability for a file, the most convenient way to do this 
is to use the DataEditorSupport class. However, this class 
depends on the DataSystems API, which is pretty much 
deprecated. If the desire is not to use the datasystems 
API, there should be a simple way to provide editing 
support with the knowledge of the FileObject only.

I am attaching a zip file which attempts to do just that. 
There is a base abstract superclass called 
org.openide.text.FileEditorSupport, which does the basic 
operations such as reading and writing to the file. Then 
there is a specialized subclass called 
org.netbeans.api.projects.ide.ProjectEditorSupport2, which 
implements specific functionality needed by the F.E.S., 
such as getting the lookup for the FileObject. (I named 
this class ProjectEditorSupport2 only because 
ProjectEditorSupport is already taken - we can later 
rename this). I can imagine that there could be other non-
abstract subclasses of F.E.S., e.g. one which would rely 
on the FSExtensions API.

This implementation is only a sketch, so it does not 
implement a lot of the functionality currently provided by 
DataEditorSupport, such as listening on rename/move 
operations of the file, providing information about the 
file in the Line objects, or detecting an external change 
of the file.

Here are some points regarding the design of the classes:

1) Currently DataObject has a role which does not have a 
direct counterpart in the DataObject-less world: holding 
the information about whether the file is modified, 
listening on the changes of the modified/unmodified state, 
and some support for locking found in the 
MultiDataObject.Entry class (the takeLock() method - note 
that I don't really know what it's for and what it does).
I am not sure where this should be put - for now I created 
a class called ModifiedSupport, which has these roles. The 
intent is that an instance of this class would be present 
in the Lookup of every fileobject (by registering it to 
MIME type "").
If we go ahead with this (or similar class), then 
DataObject should delegate to it, so we don't hold the 
state twice.

2) The FileEditorSupport class is dependent on Lookup and 
on Node for the FileObject, and it is expected that 
subclasses will provide these. I can imagine two possible 
ways to add lookup or Node for a FileObject: the Projects 
API and the FSExtensions API. The Lookup is used to get 
the ModifiedSupport class, and to find the instance of the 
FileEditorSupport after component deserialization (which 
does not work in my prototype). The Node is used to get 
the icon and display name of the editor. I am not sure how 
this can be replaced if in the future the Nodes API is 
deprecated in favor of Looks.

3) Currently, subclasses of DataEditorSupport (e.g. 
org.netbeans.modules.text.TXTEditorSupport) use a hack to 
add SaveCookie to the DataObject. This hack is both 
undesirable and impossible in the DataObject-less world. 
To implement the addition of SaveCookie into the lookup 
for the file, one has to do another not-very-nice thing: 
this is implemented by the static method 
FileEditorSupport.createLookup(...). The returned lookup 
should be used by module authors for the FileObject, 
rather than directly putting an instance of the F.E.S. 
into the object's lookup. I can't think of a more elegant 
solution.

4) Shouldn't there be a similar class for opening files in 
general (without the dependency on DataSystems), e.g. 
FileOpenSupport ?
Comment 1 Petr Jiricka 2003-06-23 18:30:14 UTC
Created attachment 10776 [details]
Zip file containing the new files for DataObject-less editing
Comment 2 David Konecny 2003-06-24 09:54:53 UTC
Thanx. Something like this will be needed and is mentioned as open
issue on FSExtension page. At the moment this is on back burner for
me. It is important and I hope to get to it ASAP but realistically not
in next couple of weeks.
Comment 3 Jesse Glick 2003-06-26 18:26:00 UTC
IMHO this should be deferred and done as a natural part of the FS
Extensions API. Projects might need to extend that support a bit (but
perhaps not, at least for simple cases).

FS Ext should cover:

- modification state of the file

- locking using plain FileLock's - which is all takeLock normally does
anyway

- general lookup for the file object ("cookies"), including the editor
support, and also permitting pluggable lookup factories which would
permit the SaveCookie to be added/removed by the support (or, a
SaveCookie2 could be introduced with an isModified / PROP_MODIFIED
extension to SaveCookie, so the editor support could directly
implement it)

Looks API, working together with FS Ext, should cover:

- display name etc. for the file - can get this directly from the
Look, no need to ask for a Node
Comment 4 Petr Jiricka 2003-06-26 19:10:31 UTC
I agree that a lot of the functionality can be implemented using the
FSExtensions and Looks APIs, esp. the lookup part and the display
name/icon part. 
I don't know what you mean by saying that FS Ext will cover the
modification state of the file: is it just that FS Ext will provide
lookup that will hold SaveCookie/SaveCookie2, or something different ?

Regarding SaveCookie2, it seems that you are suggesting that
SaveCookie2 would be present on the object permanently, regardless of
whether the file is modified or not, right? (Unlike currently
SaveCookie, which is added or removed dynamically.) Well, that's an
option, but I was worried about breaking code like:

if (myNode.getCookie(SaveCookie.class) != null) {
   displayMessage("The object is modified. Your action will be
cancelled!");
}

Would SaveCookie2 be backward compatible for the above code? 

Also, are you saying that you see no value in having a common
superclass implementing the FileObject aspect, but independent of the
Nodes, Looks and FSExtension APIs ? Do you think all this should be
implemented directly with the dependency on FSExtensions, with no
abstract superclass ?

Also, where do you think the FS Ext-based EditorSupport should be
located ? I am assuming that you don't want to introduce a dependency
of FS Ext on Looks or vice versa.
Comment 5 Jesse Glick 2003-06-26 19:35:53 UTC
I suppose that FS Ext would not directly provide the lookup facilities
for SaveCookie. Rather, it would provide a single centralized lookup
for each file, with contributions taken from arbitrary factories that
can be registered. One such factory would be supplied by the file
editor support (or perhaps by some more generic ModificationSupport,
TBD) and would contribute a SaveCookie when and only when the file was
modified. This part of the API is yet to be designed in detail, I think.

Re. compatibility concerns for "SaveCookie2" - yes, this could be a
problem. I don't know if such a change could be introduced compatibly.
It is not really necessary, but might simplify things a bit since it
would avoid the most common case where the cookies on a file need to
change on the fly.

"Also, are you saying that you see no value in having a common
superclass implementing the FileObject aspect, but independent of the
Nodes, Looks and FSExtension APIs? Do you think all this should be
implemented directly with the dependency on FSExtensions, with no
abstract superclass?" - definitely I think the main superclass should
directly use FSExtensions. Perhaps use of Looks (as I said Nodes
should be unnecessary) could be factored into a separate subclass, if
desired. I don't think there is any proposal yet for what the revised
Editor API should depend on - we just cleaned up the Datasystems API
dep, but DataEditorSupport still uses Nodes. Anyway
CloneableEditorSupport is still the neutral superclass, with some
proposed file editor support just a convenience subclass, so I think
factoring out API dependencies from it is less critical than from
other places.
Comment 6 David Konecny 2003-06-27 09:08:20 UTC
Yes, most of the stuff in this area is still TBD.
Comment 7 Jaroslav Tulach 2003-06-27 13:29:02 UTC
Currently org.openide.text does not depend on filesystems API. I
suggest not to add such dependency and keep the package clean.
Comment 8 Petr Jiricka 2003-06-27 17:24:39 UTC
Ok, point taken. Now I am convinced that the base superclass should be
tied to FSExt.

Jesse, I still don't understand how FSExt would help providing the
SaveCookie-enabled lookup. At best, FSxt could provide a
LookupContentFactory, but the module would still need to register this
factory for this particular object's MIME type. To me, that does not
sound like a huge improvement over the static method:

static Lookup createLookup(SomeEditorSupport supp)

that is in my prototype. What in particular do you mean here?

Also, there can be some problems with the use of Looks instead of Nodes:

- The support will still need to call 
  cloneableEditor.setActivatedNodes(...);
  (the windows package depends on Nodes quite heavily)

- The support will need to listen on changes in the Look and
LookSelector, which is not possible currently (but straightforward to
remedy)

- The editor will need to get hold of a look instance. I don't think
it is in Lookup normally - should it be ? Can this be relied on ?

Comment 9 Jesse Glick 2003-06-27 17:55:30 UTC
Re. SaveCookie - no, the module would not register the factory. The
file object editor support class would register a singleton factory
potentially contributing SaveCookie to any file; for a file that it in
fact had modified, it would add it. Not generally wise from a
performance standpoint to register a lookup factory for every file,
but in this case such a large number of files could potentially use it
(since so many files will have EditorCookie) that it seems acceptable
to me.

Alternately, you could request that the module which registers the
factory for the EditorCookie also delegate to a factory for SaveCookie
provided by the editor support. Syntax TBD based on how FS Ext
factories look. I guess that is more or less what your prototype is
already doing, which doesn't seem too bad to me; just one extra step
to do when adding an editor support.

(In the old days, adding a simple editor support consisted of one line
of code in a DataObject constructor. Since then it has gotten more
clever, and essentially impossible to figure out without a detailed
template. Ideally we should restore the simplicity of the original
system for the simple cases, I think. E.g. register
Files/Lookup/text/x-mytype/ed-factory.instance with a couple of attrs
saying it is a factory to create EditorCookie using a certain impl
class, and you are done.)

Re. cloneableEditor.setActivatedNodes - true, the window system
currently relies on the Nodes API, but this might be generalized in
the future (e.g. setActivatedObjects? where the Object is rendered by
a Look) so better to keep the editor support clear of it, if possible.

Not sure how the editor should find the best Look for the "file" (or
whatever it is editing). It could grab the value of the
StreamDescriptionProperty from the Document and use
Selectors.defaultTypes to find a Look for it. Maybe there is a better
way though. Probably it should be overridable by support subclasses
with special needs.
Comment 10 Petr Jiricka 2003-07-09 10:00:38 UTC
Also related to issues 34814, 34815.

http://www.netbeans.org/issues/show_bug.cgi?id=34814
http://www.netbeans.org/issues/show_bug.cgi?id=34815
Comment 11 Petr Nejedly 2003-08-01 14:26:48 UTC
Oh, I should've known about this...
I've resurrected the DS_II idea, updated the branch to registry and
looks/2 and currently I'm trying to rewrite the text module to be
fully DO-free. I have working editor support over FOs and even fully
functional SaveCookie storage. 
Although not reading Jesse's advices before, I've implemented it in
very similar way: FSExt have registered (for mime currently) an EdSup
factory which is then instructed by the EdSup to add/remove the
SaveCookie.

I've also met the Node problem, currently I'm plying with defaultTypes
Selector for it.

Generally, If we want to go Nodes-free, we also need to have some
replacement for selected nodes (selected representedObject? selected
enviroment/lookup?) in WS API/implementation.

IMO selectedObject is too narow, lookup would be more general and
better allow for BW compatibility (you can easily find the Node there,
the real representedObject (e.g. FO), interesting cookies, the
ContextAwareAction uses Lookup for this purpose already and e.g. WS
started using TCLookup.lookup(SaveCookie) for recognizing "modified"
TopComponent)


Comment 12 Jesse Glick 2003-08-05 17:58:24 UTC
Sure, "selected lookup" may work - for compat, if you select a Node in
an explorer view, Node.lookup is used (which includes the Node itself
plus all its cookies), probably via Looks.proxy. If we do a pure Look
explorer, just Look.lookupItems can be proxied to. (May still need
some way to get the representedObject out of the Lookup - TBD whether
this is actually required.)
Comment 13 Antonin Nebuzelsky 2008-04-17 15:14:19 UTC
Reassigning to new module owner mslama.