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 242226 - HardCoded DataFolder.SortModes do not conform to standard file sorting behaviour when numbers are in the filename
Summary: HardCoded DataFolder.SortModes do not conform to standard file sorting behavi...
Status: RESOLVED FIXED
Alias: None
Product: platform
Classification: Unclassified
Component: Data Systems (show other bugs)
Version: 8.0
Hardware: All All
: P3 normal (vote)
Assignee: Jaroslav Havlin
URL:
Keywords: API_REVIEW_FAST
: 237989 (view as bug list)
Depends on:
Blocks:
 
Reported: 2014-02-22 16:27 UTC by sproger1
Modified: 2015-11-09 15:38 UTC (History)
3 users (show)

See Also:
Issue Type: ENHANCEMENT
Exception Reporter:


Attachments
Proposed Patch (17.42 KB, patch)
2015-10-21 13:42 UTC, Jaroslav Havlin
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description sproger1 2014-02-22 16:27:00 UTC
Problem: Every modern operating system, file browser ... takes into account the fact that file names can have numbers and handles this case by sorting them in a natural way. i.e. If a folder contains 'f1.txt', 'f2.txt', and 'f19.txt' then most users would expect the order to be 1, 2, 19 and not 1, 19, 2. Most software out there does this by default. This would not be a big issue if there was some reasonable way for a developer to add support for their own SortMode in their Netbeans RCP app, but as I have found out(painfully) this is not the case.

Workarounds I have tried:
1) I tried creating my own DataFolder.SortMode class and replacing the 'public static final SortMode FOLDER_NAMES and NAMES' instances using reflection. But this leads to ClassCastExceptions in FolderOrder.java near line 158 <code>return ((FolderComparator)(getSortMode())).doCompare(obj1, obj2);<code>. Why is DataFolder.SortMode a public class, but FolderComparator is a package class that cannot be extended(thus making it impossible to use your own sorting order in a netbeans rcp application).

2) I then tried an even more complex solution by using javassist, cglib, and reflection to proxy the 'public static final SortMode' fields in the DataFolder object. This resulted in partial success(i.e. I created the cglib proxy and succeeded in in intercepting all public method calls on the SortMode instances), BUT, the FolderComparator.doCompare(...) method is private and thus cannot be intercepted even when using proxies. Even if this attempt succeeded, this would have been a bad programming practive, having to inject code into private fields and classes. The API should be more flexible.


After being humbled by this endeavor (waisted days trying to simply change the sorting for a netbeans rcp application). I would like to request/propose a few changes:

i) When sorting any file or folder by name, please do not use the default string comparison since this does not take into account the fact that files often have numbers in their names and thus the should be sorted using a more natural ordering system. Every modern operating system, file browser ... takes into account files with numbers. Why does the DataSystems API not do this by default.

ii) It should be possible for users/developers that wish to add/develop their own SortMode/FolderComparator to do so in a fairly simple manner, and not be blocked from doing so by the API's list of final static SortModes, private/package class FolderComparator, coupling of classes e.g. casting SortMode to FolderComparator in FolderOrder.java ...



My remaining options for solving this issue are to either set the SortMode to NONE for every folder in the project and mannually call DataFolder.setSortOrder() on every DataFolder that is created, and keep calling it every time a fileChange occurs. To me this is not efficient and would be buggy at best. Alternatively, I could patch the existing netbeans DataSystems source code and create my own version of org.openide.loaders.jar and add a maven dependency on that. This also seems to me to not be a longterm solution.

Does anyone have a better solution for creating a Netbeans RCP application that sorts files in a natural way (given the current netbeans implementation)?
Comment 1 sproger1 2014-02-22 17:01:15 UTC
Please Change:

1)
org.openide.loaders.FolderComparator.java
From:
    /** for sorting data objects by names */
    private int compareNames(Object o1, Object o2) {     
        return findFileObject(o1).getNameExt().compareTo(findFileObject(o2).getNameExt());
    }
To:
    /** for sorting data objects by names in a natural (human intuitive) way */
    private int compareNames(Object o1, Object o2) {     
        return NaturalOrderComparator.compare(fo1.getNameExt(), fo2.getNameExt());
    }

Where NaturalOrderComparator behaves like: org.apache.commons.collections.ComparatorUtils.NaturalOrderComparator
http://blog.gomilko.com/2007/05/31/natural-order-for-strings-with-numbers-in-java
http://www.java2s.com/Code/Java/Collections-Data-Structure/NaturalOrderComparator.htm
... There are many open source examples.

2) Either make FolderComparator.java a public class OR do not cast DataFolder.SortMode objects to FolderComparator objects without first checking that it is assignable...

3) Allow DataFolder.setMode() method to support custom user-defined(developer defined) SortModes and not just the hardcoded 'public static final SortMode' fields in the DataFolder class.
Comment 2 Ondrej Vrabec 2014-02-24 07:59:56 UTC
> Problem: Every modern operating system, file browser ... takes into account the fact that file names can have numbers and handles this case by sorting them in a natural way.
Really?? I always have to name my images, movis etc. with 01, 02, ..., 10,... to be correctly sorted (at least on Windows 7 OS).
Comment 3 Marek Fukala 2014-08-04 12:20:19 UTC
My Mac OSX 10.9 does alphanumeric sort of the files in the Finder app.
Comment 4 Jaroslav Havlin 2014-08-11 08:46:24 UTC
The built-in filesystem explorer in Windows 7 also supports alfanumeric sort.
So it seems reasonable to have some NaturalOrderComparator in NetBeans.
Comment 5 sproger1 2015-07-15 17:08:03 UTC
Case-insensitive sorting should also be an option. See related bug https://netbeans.org/bugzilla/show_bug.cgi?id=139753
Comment 6 Jaroslav Havlin 2015-10-21 13:42:57 UTC
Created attachment 156875 [details]
Proposed Patch
Comment 7 Jaroslav Havlin 2015-10-21 13:55:57 UTC
(In reply to sproger1 from comment #1)
> Please Change:
> 1)
> org.openide.loaders.FolderComparator.java [...]
Added new comparator, which supports natural number-sequence ordering and is case insensitive.

> 2) [...] OR do not cast DataFolder.SortMode objects to FolderComparator objects
> without first checking that it is assignable...
OK

> 3) Allow DataFolder.setMode() method to support custom SortModes [...]
It should work fine now.

Thank you for reporting.



The fix requires an API change, there is a new public field:
org.openide.loaders.DataFolder.SortMode.NATURAL
Please review this change.
Thank you.
Comment 8 sproger1 2015-10-23 02:18:25 UTC
Comment on attachment 156875 [details]
Proposed Patch

looks good. Thanks.
Comment 9 Jaroslav Havlin 2015-10-27 15:01:22 UTC
Unless there are any objections, I will integrate the patch on Thursday.
Comment 10 Jaroslav Havlin 2015-10-29 14:04:25 UTC
The patch was integrated as http://hg.netbeans.org/core-main/rev/8ada1ab80a18.

Thank you for reviewing.
Comment 11 Quality Engineering 2015-10-30 02:22:14 UTC
Integrated into 'main-silver', will be available in build *201510300002* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)

Changeset: http://hg.netbeans.org/main-silver/rev/8ada1ab80a18
User: Jaroslav Havlin <jhavlin@netbeans.org>
Log: #242226: Add natural sorting to DataFolder.SortModes
Comment 12 Jaroslav Havlin 2015-11-09 15:38:27 UTC
*** Bug 237989 has been marked as a duplicate of this bug. ***