Bug 201373 - Unable to override default OpenFileDialogFilter service providers with a @ServiceProvider "supersedes" declaration
Unable to override default OpenFileDialogFilter service providers with a @Ser...
Status: RESOLVED WORKSFORME
Product: utilities
Classification: Unclassified
Component: Open File
7.0.1
All All
: P3 (vote)
: TBD
Assigned To: Jaroslav Havlin
issues@utilities
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2011-08-26 18:51 UTC by bdschubert
Modified: 2011-10-19 13:36 UTC (History)
1 user (show)

See Also:
Issue Type: DEFECT
:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description bdschubert 2011-08-26 18:51:21 UTC
I am developing a platform application.  I want to override the "Open File..." functionality provided by the "User Utilities" ide module so that the FileChooser only displays my [*.shp] filter in the list of file types.  The problem is that the default Java [*.java] and Text [*.txt] OpenFileDialogFilters continue to be displayed in the FileChooser's list of file types, even though I specified a "supersedes" in the service provider declaration.

It seems the "supersedes" declaration isn't working.  I have successfully injected my own OpenFileDialogFilter into the FileChooser, but the Java and Text filters are still registered in the lookup.  I've tried a singular entry and arrays in the supersedes declaration but neither seemed to work.

Following is the service provider code with the "supersedes" declaration, a unit test, and the unit test output.  For your reference, you'll find the original Java and Text file filters in the FileChooser class in the org.netbeans.modules.openfile package within the User Utilities module.

Here's the short code:

package com.emxsys.gis.shapefile.filetype;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.netbeans.modules.openfile.OpenFileDialogFilter;
import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.ServiceProvider;

/**
 * This class is a service provider that supplies an OpenFileDialogFilter for *.shp files
 * to the "Open File..." feature which is provided by the "User Utilities" ide module.
 * 
 * @author Bruce Schubert <bruce@emxsys.com>
 */
@Messages(
{
    "# OpenFileDialogFilter Description",
    "OFDFD_Shapefiles=ESRI Shapefiles"
})
@ServiceProvider(service = OpenFileDialogFilter.class,
                 position = 100,
                 supersedes =
{
    "org.​netbeans.​modules.​openfile.​FileChooser.JavaFilesFilter",
    "org.​netbeans.​modules.​openfile.​FileChooser.TxtFileFilter"
})
public class ShapefileOpenFileDialogFilter extends OpenFileDialogFilter.ExtensionFilter
{
    @Override
    public FileNameExtensionFilter getFilter()
    {
        return new FileNameExtensionFilter(
                Bundle.OFDFD_Shapefiles(),
                "shp"); // NOI18N
    }
}


Here's the Unit Test codeblock:

    /**
     * Test of getFilter method, of class ShapefileOpenFileDialogFilter.
     */
    @Test
    public void testGetFilter()
    {
        System.out.println("getFilter - OpenFileDialog filters:");
        for (OpenFileDialogFilter f :
                    Lookup.getDefault().lookupAll(OpenFileDialogFilter.class)) {
                System.out.println(f.getDescriptionString());
        }
    }

Here's the Unit Test results:
------------- Standard Output ---------------
getFilter - OpenFileDialog filters:
ESRI Shapefiles
Java Files
Text Files


Thanks,
-- Bruce
Comment 1 Jaroslav Tulach 2011-08-27 17:07:27 UTC
Interesting, but you probably have to talk to the utilities module owner.
Comment 2 Jaroslav Havlin 2011-09-14 09:29:33 UTC
Hello Bruce,

please, try this, it should work:

@ServiceProvider(service = OpenFileDialogFilter.class,
position = 100,
supersedes = {
    "org.netbeans.modules.openfile.FileChooser$TxtFileFilter",
    "org.netbeans.modules.openfile.FileChooser$JavaFilesFilter"
})

(Note the dollar signs before the inner class names.)

Do not forget to run clean and build.

Note that possible solutions to enable developers to customize file filters are discussed in bug 181989.

I have created a request for enhancement in ServiceProvider documentation, see bug 202106.
Comment 3 bdschubert 2011-10-17 17:47:31 UTC
(In reply to comment #2)
Hi. Thank you for the tip. Sorry for the delay in my response.

I tried your suggestion regarding the $ for the inner classes.  That did work for the Text file filter, but strangely, not for the Java files filter.  I'm examining your link to the other bug which seems to address the Java files filter in particular.

Thank you for your help.

-- Bruce
Comment 4 Jaroslav Havlin 2011-10-18 07:33:40 UTC
Hello Bruce,

you are welcome.

It is quite strange. I tried it and it worked for both Java and Text files. Maybe there is another ServiceProvider in some other module that registers Java files filter. But I cannot reproduce it.

If you have any idea how I could help you with solving it, let me know.

Kind regards, 
 Jarda
Comment 5 bdschubert 2011-10-18 14:03:48 UTC
(In reply to comment #4)
Hi Jarda,

> .... But I cannot reproduce it.
> 
> If you have any idea how I could help you with solving it, let me know.

Thanks for the offer to help.  I'm stumped!  I'm encouraged that you were not able to reproduce it -- maybe I'm doing something wrong.  

Here's how I can reproduce it:

1) Create a new NetBeans application suite
  a) Add the library: ide > User Utilities
  b) Click the Resolve dependencies button

2) Run the application
  a) Invoke the File > Open File menu item
  b) Examine the Open dialog's file types: it should manifest All Files, Text Files and Java Files

3) Add a new module that will implement the OpenFileDialogFilter ServiceProvider
  a) Add the Lookup API module dependency
  b) Add the "non-API" User Utilities module dependency
  c) Edit the User Utilities entry and change the dependency to an Implementation Version to resolve a "The module ... is not a friend of .../org-netbeans-modules-utilities.jar" error that will occur otherwise.

4) Implement the new ServiceProvider class, for example:

  package com.emxsys.openshapefile;
  import org.netbeans.modules.openfile.OpenFileDialogFilter;
  import org.openide.util.lookup.ServiceProvider;

  @ServiceProvider(service = OpenFileDialogFilter.class, position = 100, supersedes = {
    "org.netbeans.modules.openfile.FileChooser$TxtFileFilter",
    "org.​netbeans.​modules.​openfile.​FileChooser$JavaFilesFilter" 
  })
  public class ShapefileDialogFilter extends OpenFileDialogFilter
  {
    @Override
    public String getDescriptionString() {
        return "ESRI Shapefiles";
    }
    @Override
    public String[] getSuffixes() {
        return new String[] { ".shp" }; // NOI18N
    }
  }

5) Clean/Build and Run the application
  a) Invoke the File > Open File menu item
  b) Examine the Open dialog's file types: it should manifest All Files, ESRI Shapefiles and >>> Java Files <<<<


I hope you can help.
Regards,
--Bruce
Comment 6 bdschubert 2011-10-18 14:13:40 UTC
(In reply to comment #5)
 
>   b) Add the "non-API" User Utilities module dependency
>   c) Edit the User Utilities entry and change the dependency to an
> Implementation Version to resolve a "The module ... is not a friend of
> .../org-netbeans-modules-utilities.jar" error that will occur otherwise.

Hi Jarda,

PS: Am I handling the above correctly? Somehow, it just doesn't seem right that I had to create an implementation dependency to use the OpenFileDialogFilter functionality.  

Best regards,
--Bruce
Comment 7 bdschubert 2011-10-18 16:35:20 UTC
Resolved!

Out of desperation, I opened up the META-INF.services folder in the org-netbeans-modules-utilities.jar and did a copy/paste of the Java and Text service provider names from the OpenFileDialogFilter to my "supersedes" declaration -- and the problem when away!

Strange! I can't detect a difference between the original text and the pasted text.

Anyway, I'm perplexed, but relieved. Regardless, it was a good exploration into NetBeans internals. Thanks for your help.

-- Bruce
Comment 8 Jaroslav Havlin 2011-10-19 13:10:29 UTC
Hello, it is great that it works now, but I still do not know why you had to change the JAR file. I have just tried it (following steps you had described) and everything works fine. I can see only "All Files" and "ESRI Shapefiles" in the file-type list.

> ... it just doesn't seem right that
> I had to create an implementation dependency to use 
> the OpenFileDialogFilter functionality.  

I agree, this should be changed. It is also discussed in bug 181989. There could be, hopefully, a new API in the next release (after 7.1).

Best regards, Jarda
Comment 9 bdschubert 2011-10-19 13:36:07 UTC
(In reply to comment #8)
> Hello, it is great that it works now, but I still do not know why you had to
> change the JAR file.

Oh, I'm sorry -- I wasn't clear.  I didn't change the jar file, I just copied the text from of the jar's META-INF.services via copy/paste to ensure there wasn't a typo in my own service provider declaration.  Makes me wonder if I had a weird character in my declaration that caused it to fail.

Neat thing, in the end, is that I learned how to remove the default FileChooser filters via a META-INF.services entry a common "Basic UI/Branding" module within my module suite.  E.g.:
#-org.netbeans.modules.openfile.FileChooser$JavaFilesFilter
#-org.netbeans.modules.openfile.FileChooser$TxtFileFilter

Now my filter implementation(s) don't need to specify the "supersedes", nor do are they required to know about any other filters. :)

Yeah, it was a strange situation.  The problem replicated on my end across multiple PCs, builds, and distributions.

Thanks for all your help!
-- Bruce


By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo