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 131040 - DataObject.find() does not work for own xml file type
Summary: DataObject.find() does not work for own xml file type
Status: RESOLVED FIXED
Alias: None
Product: xml
Classification: Unclassified
Component: Code (show other bugs)
Version: 6.x
Hardware: PC Linux
: P3 blocker with 2 votes (vote)
Assignee: Samaresh Panda
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-03-25 14:22 UTC by mgoe
Modified: 2008-03-28 15:27 UTC (History)
0 users

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
Module suite project showing the issue. (6.56 KB, application/x-gzip)
2008-03-25 14:23 UTC, mgoe
Details

Note You need to log in before you can comment on or make changes to this bug.
Description mgoe 2008-03-25 14:22:26 UTC
I used the "New File Type" wizard to add support for an own xml file type (NameList) recognized by an xml root 
element. The wizard created NameListDataLoader, NameListDataNode, NameListDataObject etc. for my NameList type 
(text/x-namelist+xml). But the created NameListDataNode and NameListDataObject are not used for files of my own type 
when using code like shown below:

            FileObject fileObject = FileUtil.toFileObject(myFile);
            String mimeType = fileObject.getMIMEType();
            // The following assertion is always true which is good
            assert NameListDataLoader.REQUIRED_MIME.equals(mimeType) :
                "MimeType of FileObject != NameListDataLoader.REQUIRED_MIME";
            try {
                DataObject dataObject = DataObject.find(fileObject);
                // The following assertion is always false which is bad
                assert dataObject instanceof NameListDataObject :
                    "DataObject.find() does not provide instanceof NameListDataObject";
            } catch (DataObjectNotFoundException ex) {
                Exceptions.printStackTrace(ex);
            }

In the debugger I can see that the constructor of my NameListDataLoader is called during program startup.
Creating a FileObject of an xml file of my type is successful. fileObject.getMIMEType() returns the correct mime type.
But using the FileObject in a call to DataObject.find() returns an org.netbeans.modules.xml.XMLDataObject instead of a 
NameListDataObject which I was expecting. In addition this wrong org.netbeans.modules.xml.XMLDataObject does not 
create the NameListDataNode in its createNodeDelegate() method.

Best regrads,
Martin Goettlicher
Comment 1 mgoe 2008-03-25 14:23:18 UTC
Created attachment 59020 [details]
Module suite project showing the issue.
Comment 2 mgoe 2008-03-25 14:31:24 UTC
In order to reproduce the problem please use the attached module suite project. Use the File->Find NameListDataObject 
to open a file selection dialog (this is for demonstration purposes only and not related to the problem). Select the 
following file:

<PROJECTS_DIR>/suite11/NameList/src/org/yourorghere/namelist/NameListTemplate.xml

This will produce the following assertion (showing that the wrong DataObject subclass was returned):

java.lang.AssertionError: DataObject.find() does not provide instanceof NameListDataObject
	at org.yourorghere.namelist.DataObjectFinder.performAction(DataObjectFinder.java:34)
	at org.openide.util.actions.CallableSystemAction$1.run(CallableSystemAction.java:118)
	at org.netbeans.modules.openide.util.ActionsBridge.doPerformAction(ActionsBridge.java:77)
	at org.openide.util.actions.CallableSystemAction.actionPerformed(CallableSystemAction.java:114)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
	at javax.swing.AbstractButton.doClick(AbstractButton.java:357)
	at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1220)
	at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1261)
	at java.awt.Component.processMouseEvent(Component.java:6041)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
	at java.awt.Component.processEvent(Component.java:5806)
	at java.awt.Container.processEvent(Container.java:2058)
	at java.awt.Component.dispatchEventImpl(Component.java:4413)
	at java.awt.Container.dispatchEventImpl(Container.java:2116)
	at java.awt.Component.dispatchEvent(Component.java:4243)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
	at java.awt.Container.dispatchEventImpl(Container.java:2102)
	at java.awt.Window.dispatchEventImpl(Window.java:2440)
	at java.awt.Component.dispatchEvent(Component.java:4243)
[catch] at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
	at org.netbeans.core.TimeableEventQueue.dispatchEvent(TimeableEventQueue.java:104)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Comment 3 Samaresh Panda 2008-03-26 21:20:25 UTC
I'm not sure how you've written your loader, but if you extend from UniFileLoader, you should overwrite
createMultiObject to return your data object.

For example:

    protected MultiDataObject createMultiObject (FileObject primaryFile)
            throws DataObjectExistsException, java.io.IOException {
        return new NameListDataObject (primaryFile, this);
    }

There is nothing really to fix on my side.
Comment 4 mgoe 2008-03-27 09:23:57 UTC
Please have a look at the attached test case. The loader is implemented exactly as you have written (by the way the 
loader is generated by the "New File Type" wizard). And since it does not work I would call it a bug which has to be 
fixed. If it is not fixed the platform is not usable for own applications. Please reopen this bug and fix the problem.

Best regards,
Martin Goettlicher
Comment 5 limo42 2008-03-27 17:21:07 UTC
The root of all evil is a wrong data loader ordering, seen in the list of loaders printed from the pool:
 
  org.openide.loaders.DataLoaderPool$ShadowLoader@177fa9a
  org.openide.loaders.DataLoaderPool$InstanceLoaderSystem@1712193
  org.netbeans.modules.xml.DTDDataLoader@4e17f9
  org.netbeans.modules.xml.EntityDataLoader@12ddfe4 
  org.netbeans.modules.xml.XMLDataLoader@3dfcb
  org.yourorghere.namelist.NameListDataLoader@b2c64
  org.openide.loaders.DataLoaderPool$FolderLoader@15a2dc4
  org.openide.loaders.XMLDataObject$Loader@1450bd
  org.openide.loaders.DataLoaderPool$InstanceLoader@1c0bee6
  org.openide.loaders.DataLoaderPool$DefaultLoader@1e0e954

The code the "New File Type" wizard generated in NB 6.1beta is invalid in NB 6.1beta (because it seems 
unchanged from NB 6.0). Specifically, the loader ordering entries in the manifest file are like this: 

Name: org/yourorghere/namelist/NameListDataLoader.class
Install-Before: org.openide.loaders.XMLDataObject, org.netbeans.modules.xml.core.XMLDataObject
OpenIDE-Module-Class: Loader

This doesn't work in NB 6.1 and has to be changed to...

Name: org/yourorghere/namelist/NameListDataLoader.class
Install-Before: org.openide.loaders.XMLDataObject, org.netbeans.modules.xml.XMLDataObject
OpenIDE-Module-Class: Loader

So, what *is* to fix on your side is said wizard's code generator, therefore I kindly reopended this
issue for you.

regards,

-chris
Comment 6 Samaresh Panda 2008-03-27 17:41:11 UTC
Thanks for your analysis. Let me take a look at it.
Comment 7 Samaresh Panda 2008-03-28 01:14:03 UTC
Fix integrated: http://hg.netbeans.org/main/rev/9086c160598b.
Comment 8 anba 2008-03-28 15:27:04 UTC
It seems to be that the manifest string entries in the manifest file as described by limo42 belong to the public
interfaces of the xml file type. In Netbeans 6.1 this public interface is changed (probably due to refactoring the
corresponding classes). If a developer creates an own xml file type with NetBeans 6.0 and wants to use it with Netbeans
6.1 it will compile without problems but will not work correctly (in a very subtle way). 

In my opinion public interfaces should not be refactored for backward compatibility reasons. This means that the string
interface in the manifest files should also not change between versions. A better fix of this problem would be to revert
the refactoring of the corresponding classes.

If you do not want to revert the refactoring you should clearly mention this incompatibility in the change documentation
between NetBeans 6.0 and 6.1.

Regards
Andreas