From 0bb51c9c66697fe63ba066715207deabbcc1d479 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Tue, 14 May 2019 10:16:30 +0200 Subject: [PATCH] manage remote and io exception in fanfix --- src/be/nikiroo/fanfix/Main.java | 39 +++-- .../nikiroo/fanfix/library/BasicLibrary.java | 155 +++++++++++++++--- .../nikiroo/fanfix/library/CacheLibrary.java | 32 ++-- .../nikiroo/fanfix/library/LocalLibrary.java | 8 +- .../nikiroo/fanfix/library/RemoteLibrary.java | 59 ++++--- src/be/nikiroo/fanfix/reader/BasicReader.java | 2 +- src/be/nikiroo/fanfix/reader/Reader.java | 11 +- .../nikiroo/fanfix/reader/cli/CliReader.java | 5 +- .../reader/tui/TuiReaderApplication.java | 8 +- .../reader/tui/TuiReaderMainWindow.java | 35 ++-- .../fanfix/reader/ui/GuiReaderBookInfo.java | 25 ++- .../fanfix/reader/ui/GuiReaderFrame.java | 151 ++++++++++------- .../fanfix/reader/ui/GuiReaderMainPanel.java | 40 +++-- 13 files changed, 390 insertions(+), 180 deletions(-) diff --git a/src/be/nikiroo/fanfix/Main.java b/src/be/nikiroo/fanfix/Main.java index f8c0ca25..c2f5891c 100644 --- a/src/be/nikiroo/fanfix/Main.java +++ b/src/be/nikiroo/fanfix/Main.java @@ -7,10 +7,11 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; +import javax.net.ssl.SSLException; + import be.nikiroo.fanfix.bundles.Config; import be.nikiroo.fanfix.bundles.StringId; import be.nikiroo.fanfix.data.Chapter; -import be.nikiroo.fanfix.data.MetaData; import be.nikiroo.fanfix.data.Story; import be.nikiroo.fanfix.library.BasicLibrary; import be.nikiroo.fanfix.library.CacheLibrary; @@ -564,7 +565,12 @@ public class Main { exitCode = 10; break; } - BasicReader.getReader().browse(null); + try { + BasicReader.getReader().browse(null); + } catch (IOException e) { + Instance.getTraceHandler().error(e); + exitCode = 66; + } break; case SERVER: key = Instance.getConfig().getString(Config.SERVER_KEY); @@ -590,8 +596,17 @@ public class Main { exitCode = 15; break; } + try { + new RemoteLibrary(key, host, port).exit(); + } catch (SSLException e) { + Instance.getTraceHandler().error( + "Bad access key for remote library"); + exitCode = 43; + } catch (IOException e) { + Instance.getTraceHandler().error(e); + exitCode = 44; + } - new RemoteLibrary(key, host, port).exit(); break; case REMOTE: exitCode = 255; // should not be reachable (REMOTE -> START) @@ -683,18 +698,14 @@ public class Main { * @return the exit return code (0 = success) */ private static int list(String source) { - List stories; - stories = BasicReader.getReader().getLibrary().getListBySource(source); - - for (MetaData story : stories) { - String author = ""; - if (story.getAuthor() != null && !story.getAuthor().isEmpty()) { - author = " (" + story.getAuthor() + ")"; - } - - System.out.println(story.getLuid() + ": " + story.getTitle() - + author); + BasicReader.setDefaultReaderType(ReaderType.CLI); + try { + BasicReader.getReader().browse(source); + } catch (IOException e) { + Instance.getTraceHandler().error(e); + return 66; } + return 0; } diff --git a/src/be/nikiroo/fanfix/library/BasicLibrary.java b/src/be/nikiroo/fanfix/library/BasicLibrary.java index f96506d9..3e3756fe 100644 --- a/src/be/nikiroo/fanfix/library/BasicLibrary.java +++ b/src/be/nikiroo/fanfix/library/BasicLibrary.java @@ -39,14 +39,36 @@ abstract public class BasicLibrary { * @author niki */ public enum Status { - /** The library is ready. */ - READY, + /** The library is ready and r/w. */ + READ_WRITE, + /** The library is ready, but read-only. */ + READ_ONLY, /** The library is invalid (not correctly set up). */ INVALID, /** You are not allowed to access this library. */ UNAUTHORIZED, /** The library is currently out of commission. */ - UNAVAILABLE, + UNAVAILABLE; + + /** + * The library is available (you can query it). + *

+ * It does not specify if it is read-only or not. + * + * @return TRUE if it is + */ + public boolean isReady() { + return (this == READ_WRITE || this == READ_ONLY); + } + + /** + * This library can be modified (= you are allowed to modify it). + * + * @return TRUE if it is + */ + public boolean isWritable() { + return (this == READ_WRITE); + } } /** @@ -66,7 +88,7 @@ abstract public class BasicLibrary { * @return the current status */ public Status getStatus() { - return Status.READY; + return Status.READ_WRITE; } /** @@ -81,8 +103,11 @@ abstract public class BasicLibrary { * the optional {@link Progress} * * @return the corresponding {@link Story} + * + * @throws IOException + * in case of IOException */ - public abstract File getFile(String luid, Progress pg); + public abstract File getFile(String luid, Progress pg) throws IOException; /** * Return the cover image associated to this story. @@ -91,8 +116,11 @@ abstract public class BasicLibrary { * the Library UID of the story * * @return the cover image + * + * @throws IOException + * in case of IOException */ - public abstract Image getCover(String luid); + public abstract Image getCover(String luid) throws IOException; /** * Return the cover image associated to this source. @@ -104,8 +132,11 @@ abstract public class BasicLibrary { * the source * * @return the cover image or NULL + * + * @throws IOException + * in case of IOException */ - public Image getSourceCover(String source) { + public Image getSourceCover(String source) throws IOException { Image custom = getCustomSourceCover(source); if (custom != null) { return custom; @@ -129,8 +160,11 @@ abstract public class BasicLibrary { * the author * * @return the cover image or NULL + * + * @throws IOException + * in case of IOException */ - public Image getAuthorCover(String author) { + public Image getAuthorCover(String author) throws IOException { Image custom = getCustomAuthorCover(author); if (custom != null) { return custom; @@ -153,8 +187,12 @@ abstract public class BasicLibrary { * the source to look for * * @return the custom cover or NULL if none + * + * @throws IOException + * in case of IOException */ - public Image getCustomSourceCover(@SuppressWarnings("unused") String source) { + public Image getCustomSourceCover(@SuppressWarnings("unused") String source) + throws IOException { return null; } @@ -167,8 +205,12 @@ abstract public class BasicLibrary { * the author to look for * * @return the custom cover or NULL if none + * + * @throws IOException + * in case of IOException */ - public Image getCustomAuthorCover(@SuppressWarnings("unused") String author) { + public Image getCustomAuthorCover(@SuppressWarnings("unused") String author) + throws IOException { return null; } @@ -179,8 +221,12 @@ abstract public class BasicLibrary { * the source to change * @param luid * the story LUID + * + * @throws IOException + * in case of IOException */ - public abstract void setSourceCover(String source, String luid); + public abstract void setSourceCover(String source, String luid) + throws IOException; /** * Set the author cover to the given story cover. @@ -189,8 +235,12 @@ abstract public class BasicLibrary { * the author to change * @param luid * the story LUID + * + * @throws IOException + * in case of IOException */ - public abstract void setAuthorCover(String author, String luid); + public abstract void setAuthorCover(String author, String luid) + throws IOException; /** * Return the list of stories (represented by their {@link MetaData}, which @@ -200,8 +250,11 @@ abstract public class BasicLibrary { * the optional {@link Progress} * * @return the list (can be empty but not NULL) + * + * @throws IOException + * in case of IOException */ - protected abstract List getMetas(Progress pg); + protected abstract List getMetas(Progress pg) throws IOException; /** * Invalidate the {@link Story} cache (when the content should be re-read @@ -228,8 +281,11 @@ abstract public class BasicLibrary { * * @param meta * the {@link Story} to clear from the cache + * + * @throws IOException + * in case of IOException */ - protected abstract void updateInfo(MetaData meta); + protected abstract void updateInfo(MetaData meta) throws IOException; /** * Return the next LUID that can be used. @@ -272,17 +328,27 @@ abstract public class BasicLibrary { * * @param pg * the optional progress reporter + * + * @throws IOException + * in case of IOException */ public void refresh(Progress pg) { - getMetas(pg); + try { + getMetas(pg); + } catch (IOException e) { + // We will let it fail later + } } /** * List all the known types (sources) of stories. * * @return the sources + * + * @throws IOException + * in case of IOException */ - public synchronized List getSources() { + public synchronized List getSources() throws IOException { List list = new ArrayList(); for (MetaData meta : getMetas(null)) { String storySource = meta.getSource(); @@ -308,8 +374,12 @@ abstract public class BasicLibrary { * * * @return the grouped list + * + * @throws IOException + * in case of IOException */ - public synchronized Map> getSourcesGrouped() { + public synchronized Map> getSourcesGrouped() + throws IOException { Map> map = new TreeMap>(); for (String source : getSources()) { String name; @@ -340,8 +410,11 @@ abstract public class BasicLibrary { * List all the known authors of stories. * * @return the authors + * + * @throws IOException + * in case of IOException */ - public synchronized List getAuthors() { + public synchronized List getAuthors() throws IOException { List list = new ArrayList(); for (MetaData meta : getMetas(null)) { String storyAuthor = meta.getAuthor(); @@ -372,8 +445,11 @@ abstract public class BasicLibrary { * 0-9, which may only be present or not). * * @return the authors' names, grouped by letter(s) + * + * @throws IOException + * in case of IOException */ - public Map> getAuthorsGrouped() { + public Map> getAuthorsGrouped() throws IOException { int MAX = 20; Map> groups = new TreeMap>(); @@ -448,9 +524,14 @@ abstract public class BasicLibrary { * @param car * the starting character, *, 0 or a capital * letter + * * @return the authors that fulfill the starting letter + * + * @throws IOException + * in case of IOException */ - private List getAuthorsGroup(List authors, char car) { + private List getAuthorsGroup(List authors, char car) + throws IOException { List accepted = new ArrayList(); for (String author : authors) { char first = '*'; @@ -480,8 +561,11 @@ abstract public class BasicLibrary { * Cover images MAYBE not included. * * @return the stories + * + * @throws IOException + * in case of IOException */ - public synchronized List getList() { + public synchronized List getList() throws IOException { return getMetas(null); } @@ -495,8 +579,12 @@ abstract public class BasicLibrary { * the type of story to retrieve, or NULL for all * * @return the stories + * + * @throws IOException + * in case of IOException */ - public synchronized List getListBySource(String type) { + public synchronized List getListBySource(String type) + throws IOException { List list = new ArrayList(); for (MetaData meta : getMetas(null)) { String storyType = meta.getSource(); @@ -519,8 +607,12 @@ abstract public class BasicLibrary { * the author of the stories to retrieve, or NULL for all * * @return the stories + * + * @throws IOException + * in case of IOException */ - public synchronized List getListByAuthor(String author) { + public synchronized List getListByAuthor(String author) + throws IOException { List list = new ArrayList(); for (MetaData meta : getMetas(null)) { String storyAuthor = meta.getAuthor(); @@ -541,8 +633,11 @@ abstract public class BasicLibrary { * the Library UID of the story * * @return the corresponding {@link Story} + * + * @throws IOException + * in case of IOException */ - public synchronized MetaData getInfo(String luid) { + public synchronized MetaData getInfo(String luid) throws IOException { if (luid != null) { for (MetaData meta : getMetas(null)) { if (luid.equals(meta.getLuid())) { @@ -563,8 +658,12 @@ abstract public class BasicLibrary { * the optional progress reporter * * @return the corresponding {@link Story} or NULL if not found + * + * @throws IOException + * in case of IOException */ - public synchronized Story getStory(String luid, Progress pg) { + public synchronized Story getStory(String luid, Progress pg) + throws IOException { Progress pgMetas = new Progress(); Progress pgStory = new Progress(); if (pg != null) { @@ -598,9 +697,13 @@ abstract public class BasicLibrary { * the optional progress reporter * * @return the corresponding {@link Story} or NULL if not found + * + * @throws IOException + * in case of IOException */ public synchronized Story getStory(String luid, - @SuppressWarnings("javadoc") MetaData meta, Progress pg) { + @SuppressWarnings("javadoc") MetaData meta, Progress pg) + throws IOException { if (pg == null) { pg = new Progress(); diff --git a/src/be/nikiroo/fanfix/library/CacheLibrary.java b/src/be/nikiroo/fanfix/library/CacheLibrary.java index 8f6e9c29..019acd21 100644 --- a/src/be/nikiroo/fanfix/library/CacheLibrary.java +++ b/src/be/nikiroo/fanfix/library/CacheLibrary.java @@ -52,7 +52,7 @@ public class CacheLibrary extends BasicLibrary { } @Override - protected List getMetas(Progress pg) { + protected List getMetas(Progress pg) throws IOException { if (pg == null) { pg = new Progress(); } @@ -66,7 +66,7 @@ public class CacheLibrary extends BasicLibrary { } @Override - public synchronized MetaData getInfo(String luid) { + public synchronized MetaData getInfo(String luid) throws IOException { MetaData info = cacheLib.getInfo(luid); if (info == null) { info = lib.getInfo(luid); @@ -76,7 +76,8 @@ public class CacheLibrary extends BasicLibrary { } @Override - public synchronized Story getStory(String luid, MetaData meta, Progress pg) { + public synchronized Story getStory(String luid, MetaData meta, Progress pg) + throws IOException { if (pg == null) { pg = new Progress(); } @@ -109,7 +110,8 @@ public class CacheLibrary extends BasicLibrary { } @Override - public synchronized File getFile(final String luid, Progress pg) { + public synchronized File getFile(final String luid, Progress pg) + throws IOException { if (pg == null) { pg = new Progress(); } @@ -134,7 +136,7 @@ public class CacheLibrary extends BasicLibrary { } @Override - public Image getCover(final String luid) { + public Image getCover(final String luid) throws IOException { if (isCached(luid)) { return cacheLib.getCover(luid); } @@ -144,7 +146,7 @@ public class CacheLibrary extends BasicLibrary { } @Override - public Image getSourceCover(String source) { + public Image getSourceCover(String source) throws IOException { Image custom = getCustomSourceCover(source); if (custom != null) { return custom; @@ -159,7 +161,7 @@ public class CacheLibrary extends BasicLibrary { } @Override - public Image getAuthorCover(String author) { + public Image getAuthorCover(String author) throws IOException { Image custom = getCustomAuthorCover(author); if (custom != null) { return custom; @@ -174,7 +176,7 @@ public class CacheLibrary extends BasicLibrary { } @Override - public Image getCustomSourceCover(String source) { + public Image getCustomSourceCover(String source) throws IOException { Image custom = cacheLib.getCustomSourceCover(source); if (custom == null) { custom = lib.getCustomSourceCover(source); @@ -187,7 +189,7 @@ public class CacheLibrary extends BasicLibrary { } @Override - public Image getCustomAuthorCover(String author) { + public Image getCustomAuthorCover(String author) throws IOException { Image custom = cacheLib.getCustomAuthorCover(author); if (custom == null) { custom = lib.getCustomAuthorCover(author); @@ -200,19 +202,19 @@ public class CacheLibrary extends BasicLibrary { } @Override - public void setSourceCover(String source, String luid) { + public void setSourceCover(String source, String luid) throws IOException { lib.setSourceCover(source, luid); cacheLib.setSourceCover(source, getCover(luid)); } @Override - public void setAuthorCover(String author, String luid) { + public void setAuthorCover(String author, String luid) throws IOException { lib.setAuthorCover(author, luid); cacheLib.setAuthorCover(author, getCover(luid)); } @Override - protected void updateInfo(MetaData meta) { + protected void updateInfo(MetaData meta) throws IOException { if (meta != null && metas != null) { for (int i = 0; i < metas.size(); i++) { if (metas.get(i).getLuid().equals(meta.getLuid())) { @@ -317,7 +319,11 @@ public class CacheLibrary extends BasicLibrary { * @return TRUE if it is */ public boolean isCached(String luid) { - return cacheLib.getInfo(luid) != null; + try { + return cacheLib.getInfo(luid) != null; + } catch (IOException e) { + return false; + } } /** diff --git a/src/be/nikiroo/fanfix/library/LocalLibrary.java b/src/be/nikiroo/fanfix/library/LocalLibrary.java index 59310fdc..3b0a8489 100644 --- a/src/be/nikiroo/fanfix/library/LocalLibrary.java +++ b/src/be/nikiroo/fanfix/library/LocalLibrary.java @@ -100,7 +100,7 @@ public class LocalLibrary extends BasicLibrary { } @Override - public File getFile(String luid, Progress pg) { + public File getFile(String luid, Progress pg) throws IOException { Instance.getTraceHandler().trace( this.getClass().getSimpleName() + ": get file for " + luid); @@ -122,7 +122,7 @@ public class LocalLibrary extends BasicLibrary { } @Override - public Image getCover(String luid) { + public Image getCover(String luid) throws IOException { MetaData meta = getInfo(luid); if (meta != null) { if (meta.getCover() != null) { @@ -288,12 +288,12 @@ public class LocalLibrary extends BasicLibrary { } @Override - public void setSourceCover(String source, String luid) { + public void setSourceCover(String source, String luid) throws IOException { setSourceCover(source, getCover(luid)); } @Override - public void setAuthorCover(String author, String luid) { + public void setAuthorCover(String author, String luid) throws IOException { setAuthorCover(author, getCover(luid)); } diff --git a/src/be/nikiroo/fanfix/library/RemoteLibrary.java b/src/be/nikiroo/fanfix/library/RemoteLibrary.java index 077a857c..4d8d5123 100644 --- a/src/be/nikiroo/fanfix/library/RemoteLibrary.java +++ b/src/be/nikiroo/fanfix/library/RemoteLibrary.java @@ -61,8 +61,6 @@ public class RemoteLibrary extends BasicLibrary { // informative only (server will make the actual checks) private boolean rw; - // TODO: error handling is not up to par! - /** * Create a {@link RemoteLibrary} linked to the given server. *

@@ -126,7 +124,7 @@ public class RemoteLibrary extends BasicLibrary { @Override public String getLibraryName() { - return host + ":" + port; + return (rw ? "[READ-ONLY] " : "") + host + ":" + port; } @Override @@ -150,10 +148,10 @@ public class RemoteLibrary extends BasicLibrary { if ("r/w".equals(rep)) { rw = true; - result[0] = Status.READY; + result[0] = Status.READ_WRITE; } else if ("r/o".equals(rep)) { rw = false; - result[0] = Status.READY; + result[0] = Status.READ_ONLY; } else { result[0] = Status.UNAUTHORIZED; } @@ -180,7 +178,7 @@ public class RemoteLibrary extends BasicLibrary { } @Override - public Image getCover(final String luid) { + public Image getCover(final String luid) throws IOException { final Image[] result = new Image[1]; connectRemoteAction(new RemoteAction() { @@ -197,17 +195,18 @@ public class RemoteLibrary extends BasicLibrary { } @Override - public Image getCustomSourceCover(final String source) { + public Image getCustomSourceCover(final String source) throws IOException { return getCustomCover(source, "SOURCE"); } @Override - public Image getCustomAuthorCover(final String author) { + public Image getCustomAuthorCover(final String author) throws IOException { return getCustomCover(author, "AUTHOR"); } // type: "SOURCE" or "AUTHOR" - private Image getCustomCover(final String source, final String type) { + private Image getCustomCover(final String source, final String type) + throws IOException { final Image[] result = new Image[1]; connectRemoteAction(new RemoteAction() { @@ -224,7 +223,8 @@ public class RemoteLibrary extends BasicLibrary { } @Override - public synchronized Story getStory(final String luid, Progress pg) { + public synchronized Story getStory(final String luid, Progress pg) + throws IOException { final Progress pgF = pg; final Story[] result = new Story[1]; @@ -331,18 +331,20 @@ public class RemoteLibrary extends BasicLibrary { } @Override - public void setSourceCover(final String source, final String luid) { + public void setSourceCover(final String source, final String luid) + throws IOException { setCover(source, luid, "SOURCE"); } @Override - public void setAuthorCover(final String author, final String luid) { + public void setAuthorCover(final String author, final String luid) + throws IOException { setCover(author, luid, "AUTHOR"); } // type = "SOURCE" | "AUTHOR" private void setCover(final String value, final String luid, - final String type) { + final String type) throws IOException { connectRemoteAction(new RemoteAction() { @Override public void action(ConnectActionClientObject action) @@ -445,7 +447,7 @@ public class RemoteLibrary extends BasicLibrary { /** * Stop the server. */ - public void exit() { + public void exit() throws IOException { connectRemoteAction(new RemoteAction() { @Override public void action(ConnectActionClientObject action) @@ -456,7 +458,7 @@ public class RemoteLibrary extends BasicLibrary { } @Override - public synchronized MetaData getInfo(String luid) { + public synchronized MetaData getInfo(String luid) throws IOException { List metas = getMetasList(luid, null); if (!metas.isEmpty()) { return metas.get(0); @@ -466,7 +468,7 @@ public class RemoteLibrary extends BasicLibrary { } @Override - protected List getMetas(Progress pg) { + protected List getMetas(Progress pg) throws IOException { return getMetasList("*", pg); } @@ -510,10 +512,13 @@ public class RemoteLibrary extends BasicLibrary { * @param pg * the optional progress * - * * @return the metas + * + * @throws IOException + * in case of I/O error or bad key (SSLException) */ - private List getMetasList(final String luid, Progress pg) { + private List getMetasList(final String luid, Progress pg) + throws IOException { final Progress pgF = pg; final List metas = new ArrayList(); @@ -550,7 +555,9 @@ public class RemoteLibrary extends BasicLibrary { return metas; } - private void connectRemoteAction(final RemoteAction runAction) { + private void connectRemoteAction(final RemoteAction runAction) + throws IOException { + final IOException[] err = new IOException[1]; try { final RemoteConnectAction[] array = new RemoteConnectAction[1]; RemoteConnectAction ra = new RemoteConnectAction() { @@ -561,18 +568,22 @@ public class RemoteLibrary extends BasicLibrary { @Override protected void onError(Exception e) { - if (e instanceof SSLException) { - Instance.getTraceHandler().error( - "Connection refused (bad key)"); - } else { + if (!(e instanceof IOException)) { Instance.getTraceHandler().error(e); + return; } + + err[0] = (IOException) e; } }; array[0] = ra; ra.connect(); } catch (Exception e) { - Instance.getTraceHandler().error(e); + err[0] = (IOException) e; + } + + if (err[0] != null) { + throw err[0]; } } } diff --git a/src/be/nikiroo/fanfix/reader/BasicReader.java b/src/be/nikiroo/fanfix/reader/BasicReader.java index 584bc7cb..61769c01 100644 --- a/src/be/nikiroo/fanfix/reader/BasicReader.java +++ b/src/be/nikiroo/fanfix/reader/BasicReader.java @@ -54,7 +54,7 @@ public abstract class BasicReader implements Reader { } @Override - public synchronized Story getStory(Progress pg) { + public synchronized Story getStory(Progress pg) throws IOException { if (story == null) { story = getLibrary().getStory(meta.getLuid(), pg); } diff --git a/src/be/nikiroo/fanfix/reader/Reader.java b/src/be/nikiroo/fanfix/reader/Reader.java index a0a8e806..3ecf2470 100644 --- a/src/be/nikiroo/fanfix/reader/Reader.java +++ b/src/be/nikiroo/fanfix/reader/Reader.java @@ -71,8 +71,12 @@ public interface Reader { * the optional progress * * @return the {@link Story} + * + * @throws IOException + * in case of I/O error + * */ - public Story getStory(Progress pg); + public Story getStory(Progress pg) throws IOException; /** * The {@link BasicLibrary} to load the stories from (by default, takes the @@ -167,8 +171,11 @@ public interface Reader { * @param source * the type of {@link Story} to take into account, or NULL for * all + * + * @throws IOException + * in case of I/O error */ - public void browse(String source); + public void browse(String source) throws IOException; /** * Display all supports that allow search operations. diff --git a/src/be/nikiroo/fanfix/reader/cli/CliReader.java b/src/be/nikiroo/fanfix/reader/cli/CliReader.java index a041fbf8..2a085a76 100644 --- a/src/be/nikiroo/fanfix/reader/cli/CliReader.java +++ b/src/be/nikiroo/fanfix/reader/cli/CliReader.java @@ -85,9 +85,8 @@ class CliReader extends BasicReader { } @Override - public void browse(String source) { - List stories; - stories = getLibrary().getListBySource(source); + public void browse(String source) throws IOException { + List stories = getLibrary().getListBySource(source); for (MetaData story : stories) { String author = ""; diff --git a/src/be/nikiroo/fanfix/reader/tui/TuiReaderApplication.java b/src/be/nikiroo/fanfix/reader/tui/TuiReaderApplication.java index 6f7ed3cb..b6f31ff4 100644 --- a/src/be/nikiroo/fanfix/reader/tui/TuiReaderApplication.java +++ b/src/be/nikiroo/fanfix/reader/tui/TuiReaderApplication.java @@ -82,7 +82,7 @@ class TuiReaderApplication extends TApplication implements Reader { } @Override - public Story getStory(Progress pg) { + public Story getStory(Progress pg) throws IOException { return reader.getStory(pg); } @@ -113,7 +113,11 @@ class TuiReaderApplication extends TApplication implements Reader { @Override public void browse(String source) { - reader.browse(source); + try { + reader.browse(source); + } catch (IOException e) { + Instance.getTraceHandler().error(e); + } } @Override diff --git a/src/be/nikiroo/fanfix/reader/tui/TuiReaderMainWindow.java b/src/be/nikiroo/fanfix/reader/tui/TuiReaderMainWindow.java index 932cbcbb..426355fa 100644 --- a/src/be/nikiroo/fanfix/reader/tui/TuiReaderMainWindow.java +++ b/src/be/nikiroo/fanfix/reader/tui/TuiReaderMainWindow.java @@ -159,15 +159,24 @@ class TuiReaderMainWindow extends TWindow { } else if (smode.equals("Sources")) { selectTargets.clear(); selectTargets.add("(show all)"); - for (String source : reader.getLibrary().getSources()) { - selectTargets.add(source); + try { + for (String source : reader.getLibrary().getSources()) { + selectTargets.add(source); + } + } catch (IOException e) { + Instance.getTraceHandler().error(e); } + showTarget = true; } else { selectTargets.clear(); selectTargets.add("(show all)"); - for (String author : reader.getLibrary().getAuthors()) { - selectTargets.add(author); + try { + for (String author : reader.getLibrary().getAuthors()) { + selectTargets.add(author); + } + } catch (IOException e) { + Instance.getTraceHandler().error(e); } showTarget = true; @@ -231,12 +240,18 @@ class TuiReaderMainWindow extends TWindow { */ public void refreshStories() { List metas; - if (mode == Mode.SOURCE) { - metas = reader.getLibrary().getListBySource(target); - } else if (mode == Mode.AUTHOR) { - metas = reader.getLibrary().getListByAuthor(target); - } else { - metas = reader.getLibrary().getList(); + + try { + if (mode == Mode.SOURCE) { + metas = reader.getLibrary().getListBySource(target); + } else if (mode == Mode.AUTHOR) { + metas = reader.getLibrary().getListByAuthor(target); + } else { + metas = reader.getLibrary().getList(); + } + } catch (IOException e) { + Instance.getTraceHandler().error(e); + metas = new ArrayList(); } setMetas(metas); diff --git a/src/be/nikiroo/fanfix/reader/ui/GuiReaderBookInfo.java b/src/be/nikiroo/fanfix/reader/ui/GuiReaderBookInfo.java index 3c5cc8a2..f071be02 100644 --- a/src/be/nikiroo/fanfix/reader/ui/GuiReaderBookInfo.java +++ b/src/be/nikiroo/fanfix/reader/ui/GuiReaderBookInfo.java @@ -1,5 +1,7 @@ package be.nikiroo.fanfix.reader.ui; +import java.io.IOException; + import be.nikiroo.fanfix.bundles.StringIdGui; import be.nikiroo.fanfix.data.MetaData; import be.nikiroo.fanfix.data.Story; @@ -123,8 +125,11 @@ public class GuiReaderBookInfo { * the {@link BasicLibrary} to use to fetch the image * * @return the base image + * + * @throws IOException + * in case of I/O error */ - public Image getBaseImage(BasicLibrary lib) { + public Image getBaseImage(BasicLibrary lib) throws IOException { switch (type) { case STORY: if (meta.getCover() != null) { @@ -191,8 +196,13 @@ public class GuiReaderBookInfo { GuiReaderBookInfo info = new GuiReaderBookInfo(Type.SOURCE, "source_" + source, source); - info.count = StringUtils.formatNumber(lib.getListBySource(source) - .size()); + int size = 0; + try { + size = lib.getListBySource(source).size(); + } catch (IOException e) { + } + + info.count = StringUtils.formatNumber(size); if (!info.count.isEmpty()) { info.count = GuiReader.trans(StringIdGui.BOOK_COUNT_STORIES, info.count); @@ -216,8 +226,13 @@ public class GuiReaderBookInfo { GuiReaderBookInfo info = new GuiReaderBookInfo(Type.AUTHOR, "author_" + author, author); - info.count = StringUtils.formatNumber(lib.getListByAuthor(author) - .size()); + int size = 0; + try { + size = lib.getListByAuthor(author).size(); + } catch (IOException e) { + } + + info.count = StringUtils.formatNumber(size); if (!info.count.isEmpty()) { info.count = GuiReader.trans(StringIdGui.BOOK_COUNT_STORIES, info.count); diff --git a/src/be/nikiroo/fanfix/reader/ui/GuiReaderFrame.java b/src/be/nikiroo/fanfix/reader/ui/GuiReaderFrame.java index 723ea094..a28dc8a0 100644 --- a/src/be/nikiroo/fanfix/reader/ui/GuiReaderFrame.java +++ b/src/be/nikiroo/fanfix/reader/ui/GuiReaderFrame.java @@ -31,6 +31,7 @@ import be.nikiroo.fanfix.bundles.UiConfig; import be.nikiroo.fanfix.data.MetaData; import be.nikiroo.fanfix.data.Story; import be.nikiroo.fanfix.library.BasicLibrary; +import be.nikiroo.fanfix.library.BasicLibrary.Status; import be.nikiroo.fanfix.library.LocalLibrary; import be.nikiroo.fanfix.output.BasicOutput.OutputType; import be.nikiroo.fanfix.reader.BasicReader; @@ -92,20 +93,25 @@ class GuiReaderFrame extends JFrame implements FrameHelper { @Override public JPopupMenu createBookPopup() { + Status status = reader.getLibrary().getStatus(); JPopupMenu popup = new JPopupMenu(); popup.add(createMenuItemOpenBook()); popup.addSeparator(); popup.add(createMenuItemExport()); - popup.add(createMenuItemMoveTo(true)); - popup.add(createMenuItemSetCoverForSource()); - popup.add(createMenuItemSetCoverForAuthor()); + if (status.isWritable()) { + popup.add(createMenuItemMoveTo()); + popup.add(createMenuItemSetCoverForSource()); + popup.add(createMenuItemSetCoverForAuthor()); + } popup.add(createMenuItemClearCache()); - popup.add(createMenuItemRedownload()); - popup.addSeparator(); - popup.add(createMenuItemRename(true)); - popup.add(createMenuItemSetAuthor(true)); - popup.addSeparator(); - popup.add(createMenuItemDelete()); + if (status.isWritable()) { + popup.add(createMenuItemRedownload()); + popup.addSeparator(); + popup.add(createMenuItemRename()); + popup.add(createMenuItemSetAuthor()); + popup.addSeparator(); + popup.add(createMenuItemDelete()); + } popup.addSeparator(); popup.add(createMenuItemProperties()); return popup; @@ -119,7 +125,7 @@ class GuiReaderFrame extends JFrame implements FrameHelper { } @Override - public void createMenu(boolean libOk) { + public void createMenu(Status status) { invalidate(); JMenuBar bar = new JMenuBar(); @@ -157,13 +163,15 @@ class GuiReaderFrame extends JFrame implements FrameHelper { file.add(createMenuItemOpenBook()); file.add(createMenuItemExport()); - file.add(createMenuItemMoveTo(libOk)); - file.addSeparator(); - file.add(imprt); - file.add(imprtF); - file.addSeparator(); - file.add(createMenuItemRename(libOk)); - file.add(createMenuItemSetAuthor(libOk)); + if (status.isWritable()) { + file.add(createMenuItemMoveTo()); + file.addSeparator(); + file.add(imprt); + file.add(imprtF); + file.addSeparator(); + file.add(createMenuItemRename()); + file.add(createMenuItemSetAuthor()); + } file.addSeparator(); file.add(createMenuItemProperties()); file.addSeparator(); @@ -228,8 +236,12 @@ class GuiReaderFrame extends JFrame implements FrameHelper { bar.add(view); Map> groupedSources = new HashMap>(); - if (libOk) { - groupedSources = reader.getLibrary().getSourcesGrouped(); + if (status.isReady()) { + try { + groupedSources = reader.getLibrary().getSourcesGrouped(); + } catch (IOException e) { + error(e.getLocalizedMessage(), "IOException", e); + } } JMenu sources = new JMenu(GuiReader.trans(StringIdGui.MENU_SOURCES)); sources.setMnemonic(KeyEvent.VK_S); @@ -237,8 +249,12 @@ class GuiReaderFrame extends JFrame implements FrameHelper { bar.add(sources); Map> goupedAuthors = new HashMap>(); - if (libOk) { - goupedAuthors = reader.getLibrary().getAuthorsGrouped(); + if (status.isReady()) { + try { + goupedAuthors = reader.getLibrary().getAuthorsGrouped(); + } catch (IOException e) { + error(e.getLocalizedMessage(), "IOException", e); + } } JMenu authors = new JMenu(GuiReader.trans(StringIdGui.MENU_AUTHORS)); authors.setMnemonic(KeyEvent.VK_A); @@ -344,9 +360,13 @@ class GuiReaderFrame extends JFrame implements FrameHelper { final boolean listMode) { return new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { + public void actionPerformed(ActionEvent ae) { mainPanel.removeBookPanes(); - mainPanel.addBookPane(type, listMode); + try { + mainPanel.addBookPane(type, listMode); + } catch (IOException e) { + error(e.getLocalizedMessage(), "IOException", e); + } mainPanel.refreshBooks(); } }; @@ -530,19 +550,18 @@ class GuiReaderFrame extends JFrame implements FrameHelper { /** * Create the "move to" menu item. * - * @param libOk - * the library can be queried - * * @return the item */ - private JMenuItem createMenuItemMoveTo(boolean libOk) { + private JMenuItem createMenuItemMoveTo() { JMenu changeTo = new JMenu( GuiReader.trans(StringIdGui.MENU_FILE_MOVE_TO)); changeTo.setMnemonic(KeyEvent.VK_M); Map> groupedSources = new HashMap>(); - if (libOk) { + try { groupedSources = reader.getLibrary().getSourcesGrouped(); + } catch (IOException e) { + error(e.getLocalizedMessage(), "IOException", e); } JMenuItem item = new JMenuItem( @@ -583,12 +602,9 @@ class GuiReaderFrame extends JFrame implements FrameHelper { /** * Create the "set author" menu item. * - * @param libOk - * the library can be queried - * * @return the item */ - private JMenuItem createMenuItemSetAuthor(boolean libOk) { + private JMenuItem createMenuItemSetAuthor() { JMenu changeTo = new JMenu( GuiReader.trans(StringIdGui.MENU_FILE_SET_AUTHOR)); changeTo.setMnemonic(KeyEvent.VK_A); @@ -601,34 +617,39 @@ class GuiReaderFrame extends JFrame implements FrameHelper { newItem.addActionListener(createMoveAction(ChangeAction.AUTHOR, null)); // Existing authors - if (libOk) { - Map> groupedAuthors = reader.getLibrary() - .getAuthorsGrouped(); - - if (groupedAuthors.size() > 1) { - for (String key : groupedAuthors.keySet()) { - JMenu group = new JMenu(key); - for (String value : groupedAuthors.get(key)) { - JMenuItem item = new JMenuItem( - value.isEmpty() ? GuiReader - .trans(StringIdGui.MENU_AUTHORS_UNKNOWN) - : value); - item.addActionListener(createMoveAction( - ChangeAction.AUTHOR, value)); - group.add(item); - } - changeTo.add(group); - } - } else if (groupedAuthors.size() == 1) { - for (String value : groupedAuthors.values().iterator().next()) { + Map> groupedAuthors; + + try { + groupedAuthors = reader.getLibrary().getAuthorsGrouped(); + } catch (IOException e) { + error(e.getLocalizedMessage(), "IOException", e); + groupedAuthors = new HashMap>(); + + } + + if (groupedAuthors.size() > 1) { + for (String key : groupedAuthors.keySet()) { + JMenu group = new JMenu(key); + for (String value : groupedAuthors.get(key)) { JMenuItem item = new JMenuItem( value.isEmpty() ? GuiReader .trans(StringIdGui.MENU_AUTHORS_UNKNOWN) : value); item.addActionListener(createMoveAction( ChangeAction.AUTHOR, value)); - changeTo.add(item); + group.add(item); } + changeTo.add(group); + } + } else if (groupedAuthors.size() == 1) { + for (String value : groupedAuthors.values().iterator().next()) { + JMenuItem item = new JMenuItem( + value.isEmpty() ? GuiReader + .trans(StringIdGui.MENU_AUTHORS_UNKNOWN) + : value); + item.addActionListener(createMoveAction(ChangeAction.AUTHOR, + value)); + changeTo.add(item); } } @@ -638,13 +659,9 @@ class GuiReaderFrame extends JFrame implements FrameHelper { /** * Create the "rename" menu item. * - * @param libOk - * the library can be queried - * * @return the item */ - private JMenuItem createMenuItemRename( - @SuppressWarnings("unused") boolean libOk) { + private JMenuItem createMenuItemRename() { JMenuItem changeTo = new JMenuItem( GuiReader.trans(StringIdGui.MENU_FILE_RENAME)); changeTo.setMnemonic(KeyEvent.VK_R); @@ -714,7 +731,7 @@ class GuiReaderFrame extends JFrame implements FrameHelper { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - createMenu(true); + createMenu(reader.getLibrary().getStatus()); } }); } @@ -864,7 +881,7 @@ class GuiReaderFrame extends JFrame implements FrameHelper { KeyEvent.VK_C); open.addActionListener(new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { + public void actionPerformed(ActionEvent ae) { final GuiReaderBook selectedBook = mainPanel.getSelectedBook(); if (selectedBook != null) { BasicLibrary lib = reader.getLibrary(); @@ -872,7 +889,11 @@ class GuiReaderFrame extends JFrame implements FrameHelper { String source = selectedBook.getInfo().getMeta() .getSource(); - lib.setSourceCover(source, luid); + try { + lib.setSourceCover(source, luid); + } catch (IOException e) { + error(e.getLocalizedMessage(), "IOException", e); + } GuiReaderBookInfo sourceInfo = GuiReaderBookInfo .fromSource(lib, source); @@ -896,7 +917,7 @@ class GuiReaderFrame extends JFrame implements FrameHelper { KeyEvent.VK_A); open.addActionListener(new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { + public void actionPerformed(ActionEvent ae) { final GuiReaderBook selectedBook = mainPanel.getSelectedBook(); if (selectedBook != null) { BasicLibrary lib = reader.getLibrary(); @@ -904,7 +925,11 @@ class GuiReaderFrame extends JFrame implements FrameHelper { String author = selectedBook.getInfo().getMeta() .getAuthor(); - lib.setAuthorCover(author, luid); + try { + lib.setAuthorCover(author, luid); + } catch (IOException e) { + error(e.getLocalizedMessage(), "IOException", e); + } GuiReaderBookInfo authorInfo = GuiReaderBookInfo .fromAuthor(lib, author); diff --git a/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java b/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java index cfd1e947..3153dea1 100644 --- a/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java +++ b/src/be/nikiroo/fanfix/reader/ui/GuiReaderMainPanel.java @@ -85,10 +85,10 @@ class GuiReaderMainPanel extends JPanel { *

* Will invalidate the layout. * - * @param libOk - * the library can be queried + * @param status + * the library status, must not be NULL */ - public void createMenu(boolean libOk); + public void createMenu(Status status); /** * Create a popup menu for a {@link GuiReaderBook} that represents a @@ -197,23 +197,28 @@ class GuiReaderMainPanel extends JPanel { final BasicLibrary lib = helper.getReader().getLibrary(); final Status status = lib.getStatus(); - if (status == Status.READY) { + if (status == Status.READ_WRITE) { lib.refresh(pg); } inUi(new Runnable() { @Override public void run() { - if (status == Status.READY) { - helper.createMenu(true); + if (status.isReady()) { + helper.createMenu(status); pane.setVisible(true); if (typeF == null) { - addBookPane(true, false); + try { + addBookPane(true, false); + } catch (IOException e) { + error(e.getLocalizedMessage(), + "IOException", e); + } } else { addBookPane(typeF, true); } } else { - helper.createMenu(false); + helper.createMenu(status); validate(); String desc = Instance.getTransGui().getStringX( @@ -255,8 +260,11 @@ class GuiReaderMainPanel extends JPanel { * @param listMode * TRUE to get a listing of all the sources or authors, FALSE to * get one icon per source or author + * + * @throws IOException + * in case of I/O error */ - public void addBookPane(boolean type, boolean listMode) { + public void addBookPane(boolean type, boolean listMode) throws IOException { this.currentType = type; BasicLibrary lib = helper.getReader().getLibrary(); if (type) { @@ -352,11 +360,17 @@ class GuiReaderMainPanel extends JPanel { List infos = new ArrayList(); List metas; - if (currentType) { - metas = lib.getListBySource(value); - } else { - metas = lib.getListByAuthor(value); + try { + if (currentType) { + metas = lib.getListBySource(value); + } else { + metas = lib.getListByAuthor(value); + } + } catch (IOException e) { + error(e.getLocalizedMessage(), "IOException", e); + metas = new ArrayList(); } + for (MetaData meta : metas) { infos.add(GuiReaderBookInfo.fromMeta(meta)); } -- 2.27.0