4 package eu
.etaxonomy
.cdm
.io
.markup
;
6 import java
.util
.ArrayList
;
7 import java
.util
.Collection
;
8 import java
.util
.HashMap
;
9 import java
.util
.HashSet
;
10 import java
.util
.Iterator
;
11 import java
.util
.List
;
12 import java
.util
.ListIterator
;
15 import java
.util
.UUID
;
18 * This class is supposed to find the best sorting order for features (descriptive and other).
22 public class FeatureSorter
{
25 class FeatureStatistic
{
28 boolean isAlwaysHighest
= true;
29 private int before
= 0; //number of features before this feature
30 private int after
= 0; //number of features after this feature
31 private int n
= 0; //number of occurrences of this feature
33 public FeatureStatistic(UUID uuid
) {
36 public void addValue(int index
, int total
) {
38 isAlwaysHighest
= false;
42 after
+= (total
- index
);
45 public String
toString(){
46 return uuid
!= null? uuid
.toString(): super.toString();
53 * Compute the order of features.
57 public List
<UUID
> getSortOrder(Map
<String
,List
<FeatureSorterInfo
>> listMap
){
58 List
<UUID
> result
= new ArrayList
<UUID
>();
59 //compute highest feature until all lists are empty
60 removeEmptyLists(listMap
);
61 while (! listMap
.isEmpty()){
62 Map
<UUID
,FeatureStatistic
> statisticMap
= computeStatistic(listMap
);
63 FeatureStatistic best
= findBest(statisticMap
);
64 result
.add(best
.uuid
);
65 removeFromLists(listMap
, best
.uuid
);
71 private void removeEmptyLists(Map
<String
, List
<FeatureSorterInfo
>> listMap
) {
72 Set
<String
> keysToRemove
= new HashSet
<String
>();
73 for(String key
: listMap
.keySet()){
74 List
<FeatureSorterInfo
> list
= listMap
.get(key
);
76 keysToRemove
.add(key
);
79 for (String key
: keysToRemove
){
87 * Removes all entries for given uuid from orderLists and removes empty lists from map.
91 private void removeFromLists(Map
<String
, List
<FeatureSorterInfo
>> orderLists
, UUID uuid
) {
93 Set
<String
> keySet
= orderLists
.keySet();
94 Iterator
<String
> keySetIterator
= keySet
.iterator();
95 while (keySetIterator
.hasNext()){
96 String key
= keySetIterator
.next();
97 List
<FeatureSorterInfo
> list
= orderLists
.get(key
);
98 Iterator
<FeatureSorterInfo
> it
= list
.listIterator();
100 FeatureSorterInfo info
= it
.next();
101 if (info
.getUuid().equals(uuid
)){
104 keySetIterator
.remove();
112 private FeatureStatistic
findBest(Map
<UUID
, FeatureStatistic
> statisticMap
) {
113 FeatureStatistic result
;
114 Set
<FeatureStatistic
> highest
= getOnlyHighestFeatures(statisticMap
);
115 if (highest
.size() == 1){
116 result
= highest
.iterator().next();
117 }else if (highest
.size() > 1){
118 result
= findBestOfHighest(highest
);
120 result
= findBestOfNonHighest(statisticMap
);
127 * If multiple features do all have no higher feature in any list, this method
128 * can be called to use an alternative criteria to find the "highest" feature.
132 private FeatureStatistic
findBestOfHighest(Set
<FeatureStatistic
> highest
) {
133 //current implementation: find the one with the highest "after" value
134 FeatureStatistic result
= highest
.iterator().next();
135 int bestAfter
= result
.after
;
136 for (FeatureStatistic statistic
: highest
){
137 if (statistic
.after
> bestAfter
){
139 bestAfter
= statistic
.after
;
147 * If no feature is always highest this method can be called to use an alternative criteria
148 * to find the "highest" feature.
150 * @param statisticMap
153 private FeatureStatistic
findBestOfNonHighest(Map
<UUID
, FeatureStatistic
> statisticMap
) {
154 //current implementation: find the one with the lowest "before" value
155 //TODO better use before/n ??
156 Collection
<FeatureStatistic
> statistics
= statisticMap
.values();
157 FeatureStatistic result
= statistics
.iterator().next();
158 int bestBefore
= result
.before
;
159 for (FeatureStatistic statistic
: statistics
){
160 if (statistic
.before
< bestBefore
){
162 bestBefore
= statistic
.before
;
169 private Set
<FeatureStatistic
> getOnlyHighestFeatures(Map
<UUID
, FeatureStatistic
> statisticMap
) {
170 Set
<FeatureStatistic
> result
= new HashSet
<FeatureStatistic
>();
171 for (FeatureStatistic statistic
: statisticMap
.values()){
172 if (statistic
.isAlwaysHighest
){
173 result
.add(statistic
);
180 private Map
<UUID
, FeatureStatistic
> computeStatistic(Map
<String
,List
<FeatureSorterInfo
>> orderLists
) {
181 Map
<UUID
, FeatureStatistic
> result
= new HashMap
<UUID
, FeatureStatistic
>();
182 for (String key
: orderLists
.keySet()){
183 List
<FeatureSorterInfo
> list
= orderLists
.get(key
);
185 for (FeatureSorterInfo info
: list
){
186 FeatureStatistic statistic
= getFeatureStatistic(info
, result
);
187 int index
= list
.indexOf(info
);
188 statistic
.addValue(index
,n
);
195 private FeatureStatistic
getFeatureStatistic(FeatureSorterInfo info
, Map
<UUID
, FeatureStatistic
> statisticMap
) {
196 UUID uuid
= info
.getUuid();
197 FeatureStatistic result
= statisticMap
.get(uuid
);
199 result
= new FeatureStatistic(uuid
);
200 statisticMap
.put(uuid
, result
);