lib: sort fixes
[nikiroo-utils.git] / src / be / nikiroo / fanfix / library / MetaResultList.java
1 package be.nikiroo.fanfix.library;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collections;
6 import java.util.Comparator;
7 import java.util.List;
8
9 import be.nikiroo.fanfix.data.MetaData;
10
11 public class MetaResultList {
12 private List<MetaData> metas;
13
14 // Lazy lists:
15 // TODO: sync-protect them?
16 private List<String> sources;
17 private List<String> authors;
18 private List<String> tags;
19
20 // can be null (will consider it empty)
21 public MetaResultList(List<MetaData> metas) {
22 if (metas == null) {
23 metas = new ArrayList<MetaData>();
24 }
25
26 Collections.sort(metas);
27 this.metas = metas;
28 }
29
30 // not NULL
31 // sorted
32 public List<MetaData> getMetas() {
33 return metas;
34 }
35
36 public List<String> getSources() {
37 if (sources == null) {
38 sources = new ArrayList<String>();
39 for (MetaData meta : metas) {
40 if (!sources.contains(meta.getSource()))
41 sources.add(meta.getSource());
42 }
43 sort(sources);
44 }
45
46 return sources;
47 }
48
49 // A -> (A), A/ -> (A, A/*) if we can find something for "*"
50 public List<String> getSources(String source) {
51 List<String> linked = new ArrayList<String>();
52 if (source != null && !source.isEmpty()) {
53 if (!source.endsWith("/")) {
54 linked.add(source);
55 } else {
56 linked.add(source.substring(0, source.length() - 1));
57 for (String src : getSources()) {
58 if (src.startsWith(source)) {
59 linked.add(src);
60 }
61 }
62 }
63 }
64
65 sort(linked);
66 return linked;
67 }
68
69 public List<String> getAuthors() {
70 if (authors == null) {
71 authors = new ArrayList<String>();
72 for (MetaData meta : metas) {
73 if (!authors.contains(meta.getAuthor()))
74 authors.add(meta.getAuthor());
75 }
76 sort(authors);
77 }
78
79 return authors;
80 }
81
82 public List<String> getTags() {
83 if (tags == null) {
84 tags = new ArrayList<String>();
85 for (MetaData meta : metas) {
86 for (String tag : meta.getTags()) {
87 if (!tags.contains(tag))
88 tags.add(tag);
89 }
90 }
91 sort(tags);
92 }
93
94 return tags;
95 }
96
97 // helper
98 public List<MetaData> filter(String source, String author, String tag) {
99 List<String> sources = source == null ? null : Arrays.asList(source);
100 List<String> authors = author == null ? null : Arrays.asList(author);
101 List<String> tags = tag == null ? null : Arrays.asList(tag);
102
103 return filter(sources, authors, tags);
104 }
105
106 // null or empty -> no check, rest = must be included
107 // source: a source ending in "/" means "this or any source starting with
108 // this",
109 // i;e., to enable source hierarchy
110 // + sorted
111 public List<MetaData> filter(List<String> sources, List<String> authors,
112 List<String> tags) {
113 if (sources != null && sources.isEmpty())
114 sources = null;
115 if (authors != null && authors.isEmpty())
116 authors = null;
117 if (tags != null && tags.isEmpty())
118 tags = null;
119
120 // Quick check
121 if (sources == null && authors == null && tags == null) {
122 return metas;
123 }
124
125 // allow "sources/" hierarchy
126 if (sources != null) {
127 List<String> folders = new ArrayList<String>();
128 List<String> leaves = new ArrayList<String>();
129 for (String source : sources) {
130 if (source.endsWith("/")) {
131 if (!folders.contains(source))
132 folders.add(source);
133 } else {
134 if (!leaves.contains(source))
135 leaves.add(source);
136 }
137 }
138
139 sources = leaves;
140 for (String folder : folders) {
141 for (String otherLeaf : getSources(folder)) {
142 if (!sources.contains(otherLeaf)) {
143 sources.add(otherLeaf);
144 }
145 }
146 }
147 }
148
149 List<MetaData> result = new ArrayList<MetaData>();
150 for (MetaData meta : metas) {
151 if (sources != null && !sources.contains(meta.getSource())) {
152 continue;
153 }
154 if (authors != null && !authors.contains(meta.getAuthor())) {
155 continue;
156 }
157
158 if (tags != null) {
159 boolean keep = false;
160 for (String thisTag : meta.getTags()) {
161 if (tags.contains(thisTag))
162 keep = true;
163 }
164
165 if (!keep)
166 continue;
167 }
168
169 result.add(meta);
170 }
171
172 Collections.sort(result);
173 return result;
174 }
175
176 /**
177 * Sort the given {@link String} values, ignoring case.
178 *
179 * @param values
180 * the values to sort
181 */
182 private void sort(List<String> values) {
183 Collections.sort(values, new Comparator<String>() {
184 @Override
185 public int compare(String o1, String o2) {
186 return ("" + o1).compareToIgnoreCase("" + o2);
187 }
188 });
189 }
190 }