prepare new system for getting metas in libraries
authorNiki Roo <niki@nikiroo.be>
Tue, 7 Apr 2020 17:47:58 +0000 (19:47 +0200)
committerNiki Roo <niki@nikiroo.be>
Tue, 7 Apr 2020 17:47:58 +0000 (19:47 +0200)
src/be/nikiroo/fanfix/library/BasicLibrary.java
src/be/nikiroo/fanfix/library/CacheLibrary.java
src/be/nikiroo/fanfix/library/MetaResultList.java [new file with mode: 0644]

index c558384d380526819f36a8dac9553b89d33517ca..b92e5b078b01047e4e40375ec401f47b4f6bfe73 100644 (file)
@@ -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.
         * <p>
@@ -245,6 +252,8 @@ abstract public class BasicLibrary {
        /**
         * Return the list of stories (represented by their {@link MetaData}, which
         * <b>MAY</b> not have the cover included).
+        * <p>
+        * The returned list <b>MUST</b> 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.
         * <p>
         * 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<MetaData> getListBySource(String type)
-                       throws IOException {
-               List<MetaData> list = new ArrayList<MetaData>();
-               for (MetaData meta : getMetas(null)) {
-                       String storyType = meta.getSource();
-                       if (type == null || type.equalsIgnoreCase(storyType)) {
-                               list.add(meta);
-                       }
+       @Deprecated
+       public synchronized List<MetaData> getListBySource(String source) throws IOException {
+               List<String> sources = null;
+               if (source != null) {
+                       sources = new ArrayList<String>();
+                       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<MetaData> getListByAuthor(String author)
-                       throws IOException {
-               List<MetaData> list = new ArrayList<MetaData>();
-               for (MetaData meta : getMetas(null)) {
-                       String storyAuthor = meta.getAuthor();
-                       if (author == null || author.equalsIgnoreCase(storyAuthor)) {
-                               list.add(meta);
-                       }
+       public synchronized List<MetaData> getListByAuthor(String author) throws IOException {
+               List<String> authors = null;
+               if (author != null) {
+                       authors = new ArrayList<String>();
+                       authors.add(author);
                }
 
-               Collections.sort(list);
-               return list;
+               return getList(null).filter(null, authors, null);
        }
 
        /**
index cccfedba0cfd29ec755034b9197f7a7495dd0b38..14d28cf14f7b1fbe1782d012d3d70203fec07958 100644 (file)
@@ -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<MetaData>(metas);
        }
 
        @Override
diff --git a/src/be/nikiroo/fanfix/library/MetaResultList.java b/src/be/nikiroo/fanfix/library/MetaResultList.java
new file mode 100644 (file)
index 0000000..3aa167f
--- /dev/null
@@ -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<MetaData> metas;
+
+       // Lazy lists:
+       // TODO: sync-protect them?
+       private List<String> sources;
+       private List<String> authors;
+       private List<String> tags;
+
+       // can be null (will consider it empty)
+       public MetaResultList(List<MetaData> metas) {
+               if (metas == null) {
+                       metas = new ArrayList<MetaData>();
+               }
+
+               Collections.sort(metas);
+               this.metas = metas;
+       }
+
+       // not NULL
+       // sorted
+       public List<MetaData> getMetas() {
+               return metas;
+       }
+
+       public List<String> getSources() {
+               if (sources == null) {
+                       sources = new ArrayList<String>();
+                       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<String> getSources(String source) {
+               List<String> linked = new ArrayList<String>();
+               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<String> getAuthors() {
+               if (authors == null) {
+                       authors = new ArrayList<String>();
+                       for (MetaData meta : metas) {
+                               if (!authors.contains(meta.getAuthor()))
+                                       authors.add(meta.getAuthor());
+                       }
+               }
+
+               return authors;
+       }
+
+       public List<String> getTags() {
+               if (tags == null) {
+                       tags = new ArrayList<String>();
+                       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<MetaData> filter(List<String> sources, List<String> authors, List<String> 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<String> folders = new ArrayList<String>();
+                       List<String> leaves = new ArrayList<String>();
+                       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<MetaData> result = new ArrayList<MetaData>();
+               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;
+       }
+}