From 1f2a7d5fe14f98b5dd762207eeaff90494fe102e Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Tue, 7 Apr 2020 19:47:58 +0200 Subject: [PATCH] prepare new system for getting metas in libraries --- .../nikiroo/fanfix/library/BasicLibrary.java | 58 ++++--- .../nikiroo/fanfix/library/CacheLibrary.java | 3 +- .../fanfix/library/MetaResultList.java | 158 ++++++++++++++++++ 3 files changed, 192 insertions(+), 27 deletions(-) create mode 100644 src/be/nikiroo/fanfix/library/MetaResultList.java diff --git a/src/be/nikiroo/fanfix/library/BasicLibrary.java b/src/be/nikiroo/fanfix/library/BasicLibrary.java index c558384..b92e5b0 100644 --- a/src/be/nikiroo/fanfix/library/BasicLibrary.java +++ b/src/be/nikiroo/fanfix/library/BasicLibrary.java @@ -122,6 +122,13 @@ abstract public class BasicLibrary { */ public abstract Image getCover(String luid) throws IOException; + // TODO: ensure it is the main used interface + public synchronized MetaResultList getList(Progress pg) throws IOException { + return new MetaResultList(getMetas(pg)); + } + + //TODO: make something for (normal and custom) not-story covers + /** * Return the cover image associated to this source. *

@@ -245,6 +252,8 @@ abstract public class BasicLibrary { /** * Return the list of stories (represented by their {@link MetaData}, which * MAY not have the cover included). + *

+ * The returned list MUST be a copy, not the original one. * * @param pg * the optional {@link Progress} @@ -563,31 +572,29 @@ abstract public class BasicLibrary { } /** - * List all the stories of the given source type in the {@link BasicLibrary} - * , or all the stories if NULL is passed as a type. + * List all the stories of the given source type in the {@link BasicLibrary} , + * or all the stories if NULL is passed as a type. *

* Cover images not included. * - * @param type - * the type of story to retrieve, or NULL for all + * @param source the type of story to retrieve, or NULL for all * * @return the stories * - * @throws IOException - * in case of IOException + * @throws IOException in case of IOException + * + * @deprecated use {@link BasicLibrary#getList(Progress)} and + * {@link MetaResultList#filter(List, List, List)} */ - public synchronized List getListBySource(String type) - throws IOException { - List list = new ArrayList(); - for (MetaData meta : getMetas(null)) { - String storyType = meta.getSource(); - if (type == null || type.equalsIgnoreCase(storyType)) { - list.add(meta); - } + @Deprecated + public synchronized List getListBySource(String source) throws IOException { + List sources = null; + if (source != null) { + sources = new ArrayList(); + sources.add(source); } - Collections.sort(list); - return list; + return getList(null).filter(sources, null, null); } /** @@ -603,19 +610,18 @@ abstract public class BasicLibrary { * * @throws IOException * in case of IOException + * + * @deprecated use {@link BasicLibrary#getList(Progress)} and + * {@link MetaResultList#filter(List, List, List)} */ - public synchronized List getListByAuthor(String author) - throws IOException { - List list = new ArrayList(); - for (MetaData meta : getMetas(null)) { - String storyAuthor = meta.getAuthor(); - if (author == null || author.equalsIgnoreCase(storyAuthor)) { - list.add(meta); - } + public synchronized List getListByAuthor(String author) throws IOException { + List authors = null; + if (author != null) { + authors = new ArrayList(); + authors.add(author); } - Collections.sort(list); - return list; + return getList(null).filter(null, authors, null); } /** diff --git a/src/be/nikiroo/fanfix/library/CacheLibrary.java b/src/be/nikiroo/fanfix/library/CacheLibrary.java index cccfedb..14d28cf 100644 --- a/src/be/nikiroo/fanfix/library/CacheLibrary.java +++ b/src/be/nikiroo/fanfix/library/CacheLibrary.java @@ -3,6 +3,7 @@ package be.nikiroo.fanfix.library; import java.io.File; import java.io.IOException; import java.net.URL; +import java.util.ArrayList; import java.util.List; import be.nikiroo.fanfix.Instance; @@ -63,7 +64,7 @@ public class CacheLibrary extends BasicLibrary { } pg.done(); - return metas; + return new ArrayList(metas); } @Override diff --git a/src/be/nikiroo/fanfix/library/MetaResultList.java b/src/be/nikiroo/fanfix/library/MetaResultList.java new file mode 100644 index 0000000..3aa167f --- /dev/null +++ b/src/be/nikiroo/fanfix/library/MetaResultList.java @@ -0,0 +1,158 @@ +package be.nikiroo.fanfix.library; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import be.nikiroo.fanfix.data.MetaData; + +public class MetaResultList { + private List metas; + + // Lazy lists: + // TODO: sync-protect them? + private List sources; + private List authors; + private List tags; + + // can be null (will consider it empty) + public MetaResultList(List metas) { + if (metas == null) { + metas = new ArrayList(); + } + + Collections.sort(metas); + this.metas = metas; + } + + // not NULL + // sorted + public List getMetas() { + return metas; + } + + public List getSources() { + if (sources == null) { + sources = new ArrayList(); + for (MetaData meta : metas) { + if (!sources.contains(meta.getSource())) + sources.add(meta.getSource()); + } + } + + return sources; + } + + // A -> (A), A/ -> (A, A/*) if we can find something for "*" + public List getSources(String source) { + List linked = new ArrayList(); + if (source != null && !source.isEmpty()) { + if (!source.endsWith("/")) { + linked.add(source); + } else { + linked.add(source.substring(0, source.length() - 1)); + for (String src : getSources()) { + if (src.startsWith(source)) { + linked.add(src); + } + } + } + } + + return linked; + } + + public List getAuthors() { + if (authors == null) { + authors = new ArrayList(); + for (MetaData meta : metas) { + if (!authors.contains(meta.getAuthor())) + authors.add(meta.getAuthor()); + } + } + + return authors; + } + + public List getTags() { + if (tags == null) { + tags = new ArrayList(); + for (MetaData meta : metas) { + for (String tag : meta.getTags()) { + if (!tags.contains(tag)) + tags.add(tag); + } + } + } + + return authors; + } + + // null or empty -> no check, rest = must be included + // source: a source ending in "/" means "this or any source starting with this", + // i;e., to enable source hierarchy + // + sorted + public List filter(List sources, List authors, List tags) { + if (sources != null && sources.isEmpty()) + sources = null; + if (authors != null && authors.isEmpty()) + authors = null; + if (tags != null && tags.isEmpty()) + tags = null; + + // Quick check + if (sources == null && authors == null && tags == null) { + return metas; + } + + // allow "sources/" hierarchy + if (sources != null) { + List folders = new ArrayList(); + List leaves = new ArrayList(); + for (String source : sources) { + if (source.endsWith("/")) { + if (!folders.contains(source)) + folders.add(source); + } else { + if (!leaves.contains(source)) + leaves.add(source); + } + } + + sources = leaves; + for (String folder : folders) { + for (String otherLeaf : getSources(folder)) { + if (!sources.contains(otherLeaf)) { + sources.add(otherLeaf); + } + } + } + } + + List result = new ArrayList(); + for (MetaData meta : metas) { + if (sources != null && !sources.contains(meta.getSource())) { + continue; + } + if (authors != null && !authors.contains(meta.getAuthor())) { + continue; + } + + if (tags != null) { + boolean keep = false; + for (String thisTag : meta.getTags()) { + if (tags.contains(thisTag)) + keep = true; + } + + if (!keep) + continue; + } + + result.add(meta); + } + + Collections.sort(result); + return result; + } +} -- 2.27.0