Merge branch 'subtree'
[fanfix.git] / src / be / nikiroo / fanfix / library / RemoteLibraryServer.java
index ada467311d1e2d77801b6a7df379ee0272dad3f4..4ee3f74d221c3497978cc57d70fc935fd466579f 100644 (file)
@@ -2,7 +2,6 @@ package be.nikiroo.fanfix.library;
 
 import java.io.IOException;
 import java.net.URL;
-import java.nio.file.AccessDeniedException;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
@@ -81,7 +80,7 @@ public class RemoteLibraryServer extends ServerObject {
         */
        public RemoteLibraryServer(String key, int port) throws IOException {
                super("Fanfix remote library", port, key);
-               setTraceHandler(Instance.getTraceHandler());
+               setTraceHandler(Instance.getInstance().getTraceHandler());
        }
 
        @Override
@@ -111,8 +110,7 @@ public class RemoteLibraryServer extends ServerObject {
                        }
                }
 
-               List<String> whitelist = Instance.getConfig().getList(
-                               Config.SERVER_WHITELIST);
+               List<String> whitelist = Instance.getInstance().getConfig().getList(Config.SERVER_WHITELIST);
                if (whitelist == null) {
                        whitelist = new ArrayList<String>();
                }
@@ -121,10 +119,9 @@ public class RemoteLibraryServer extends ServerObject {
                        wl = false;
                }
 
-               rw = Instance.getConfig().getBoolean(Config.SERVER_RW, rw);
+               rw = Instance.getInstance().getConfig().getBoolean(Config.SERVER_RW, rw);
                if (!subkey.isEmpty()) {
-                       List<String> allowed = Instance.getConfig().getList(
-                                       Config.SERVER_ALLOWED_SUBKEYS);
+                       List<String> allowed = Instance.getInstance().getConfig().getList(Config.SERVER_ALLOWED_SUBKEYS);
                        if (allowed.contains(subkey)) {
                                if ((subkey + "|").contains("|rw|")) {
                                        rw = true;
@@ -142,14 +139,14 @@ public class RemoteLibraryServer extends ServerObject {
                for (Object arg : args) {
                        trace += arg + " ";
                }
-               System.out.println(trace);
+               long now = System.currentTimeMillis();
+               System.out.println(StringUtils.fromTime(now) + ": " + trace);
 
                Object rep = null;
-               Exception oops = null;
                try {
                        rep = doRequest(action, command, args, rw, whitelist);
-               } catch (Exception e) {
-                       oops = e;
+               } catch (IOException e) {
+                       rep = new RemoteLibraryException(e, true);
                }
 
                commands.put(id, command);
@@ -157,10 +154,6 @@ public class RemoteLibraryServer extends ServerObject {
                rws.put(id, rw);
                times.put(id, (new Date().getTime() - start));
 
-               if (oops != null) {
-                       throw oops;
-               }
-
                return rep;
        }
 
@@ -185,9 +178,12 @@ public class RemoteLibraryServer extends ServerObject {
 
                String rec = StringUtils.formatNumber(bytesReceived) + "b";
                String sent = StringUtils.formatNumber(bytesSent) + "b";
-               System.out.println(String.format("%s[>%s]: (%s sent, %s rec) in %d ms",
-                               display(whitelist, rw), commands.get(id), sent, rec,
-                               times.get(id)));
+               long now = System.currentTimeMillis();
+               System.out.println(StringUtils.fromTime(now)
+                               + ": "
+                               + String.format("%s[>%s]: (%s sent, %s rec) in %d ms",
+                                               display(whitelist, rw), commands.get(id), sent, rec,
+                                               times.get(id)));
 
                commands.remove(id);
                times.remove(id);
@@ -205,21 +201,13 @@ public class RemoteLibraryServer extends ServerObject {
                        if ("*".equals(args[0])) {
                                Progress pg = createPgForwarder(action);
 
-                               for (MetaData meta : Instance.getLibrary().getMetas(pg)) {
-                                       MetaData light;
-                                       if (meta.getCover() == null) {
-                                               light = meta;
-                                       } else {
-                                               light = meta.clone();
-                                               light.setCover(null);
-                                       }
-
-                                       metas.add(light);
+                               for (MetaData meta : Instance.getInstance().getLibrary().getMetas(pg)) {
+                                       metas.add(removeCover(meta));
                                }
 
                                forcePgDoneSent(pg);
                        } else {
-                               MetaData meta = Instance.getLibrary().getInfo((String) args[0]);
+                               MetaData meta = Instance.getInstance().getLibrary().getInfo((String) args[0]);
                                MetaData light;
                                if (meta.getCover() == null) {
                                        light = meta;
@@ -242,7 +230,7 @@ public class RemoteLibraryServer extends ServerObject {
 
                        return metas.toArray(new MetaData[0]);
                } else if ("GET_STORY".equals(command)) {
-                       MetaData meta = Instance.getLibrary().getInfo((String) args[0]);
+                       MetaData meta = Instance.getInstance().getLibrary().getInfo((String) args[0]);
                        if (meta == null) {
                                return null;
                        }
@@ -259,16 +247,15 @@ public class RemoteLibraryServer extends ServerObject {
                        action.send(meta);
                        action.rec();
 
-                       Story story = Instance.getLibrary()
-                                       .getStory((String) args[0], null);
+                       Story story = Instance.getInstance().getLibrary().getStory((String) args[0], null);
                        for (Object obj : breakStory(story)) {
                                action.send(obj);
                                action.rec();
                        }
                } else if ("SAVE_STORY".equals(command)) {
                        if (!rw) {
-                               throw new AccessDeniedException("" + args[0], null,
-                                               "Read-Only remote library");
+                               throw new RemoteLibraryException("Read-Only remote library: "
+                                               + args[0], false);
                        }
 
                        List<Object> list = new ArrayList<Object>();
@@ -282,68 +269,62 @@ public class RemoteLibraryServer extends ServerObject {
                        }
 
                        Story story = rebuildStory(list);
-                       Instance.getLibrary().save(story, (String) args[0], null);
+                       Instance.getInstance().getLibrary().save(story, (String) args[0], null);
                        return story.getMeta().getLuid();
                } else if ("IMPORT".equals(command)) {
                        if (!rw) {
-                               throw new AccessDeniedException("" + args[0], null,
-                                               "Read-Only remote library");
+                               throw new RemoteLibraryException("Read-Only remote library: "
+                                               + args[0], false);
                        }
 
                        Progress pg = createPgForwarder(action);
-                       Story story = Instance.getLibrary().imprt(
-                                       new URL((String) args[0]), pg);
+                       MetaData meta = Instance.getInstance().getLibrary().imprt(new URL((String) args[0]), pg);
                        forcePgDoneSent(pg);
-                       return story.getMeta().getLuid();
+                       return meta.getLuid();
                } else if ("DELETE_STORY".equals(command)) {
                        if (!rw) {
-                               throw new AccessDeniedException("" + args[0], null,
-                                               "Read-Only remote library");
+                               throw new RemoteLibraryException("Read-Only remote library: "
+                                               + args[0], false);
                        }
 
-                       Instance.getLibrary().delete((String) args[0]);
+                       Instance.getInstance().getLibrary().delete((String) args[0]);
                } else if ("GET_COVER".equals(command)) {
-                       return Instance.getLibrary().getCover((String) args[0]);
+                       return Instance.getInstance().getLibrary().getCover((String) args[0]);
                } else if ("GET_CUSTOM_COVER".equals(command)) {
                        if ("SOURCE".equals(args[0])) {
-                               return Instance.getLibrary().getCustomSourceCover(
-                                               (String) args[1]);
+                               return Instance.getInstance().getLibrary().getCustomSourceCover((String) args[1]);
                        } else if ("AUTHOR".equals(args[0])) {
-                               return Instance.getLibrary().getCustomAuthorCover(
-                                               (String) args[1]);
+                               return Instance.getInstance().getLibrary().getCustomAuthorCover((String) args[1]);
                        } else {
                                return null;
                        }
                } else if ("SET_COVER".equals(command)) {
                        if (!rw) {
-                               throw new AccessDeniedException("" + args[0], "" + args[1],
-                                               "Read-Only remote library");
+                               throw new RemoteLibraryException("Read-Only remote library: "
+                                               + args[0] + ", " + args[1], false);
                        }
 
                        if ("SOURCE".equals(args[0])) {
-                               Instance.getLibrary().setSourceCover((String) args[1],
-                                               (String) args[2]);
+                               Instance.getInstance().getLibrary().setSourceCover((String) args[1], (String) args[2]);
                        } else if ("AUTHOR".equals(args[0])) {
-                               Instance.getLibrary().setAuthorCover((String) args[1],
-                                               (String) args[2]);
+                               Instance.getInstance().getLibrary().setAuthorCover((String) args[1], (String) args[2]);
                        }
                } else if ("CHANGE_STA".equals(command)) {
                        if (!rw) {
-                               throw new AccessDeniedException("" + args[0], "" + args[1],
-                                               "Read-Only remote library");
+                               throw new RemoteLibraryException("Read-Only remote library: " + args[0] + ", " + args[1], false);
                        }
 
                        Progress pg = createPgForwarder(action);
-                       Instance.getLibrary().changeSTA((String) args[0], (String) args[1],
-                                       (String) args[2], (String) args[3], pg);
+                       Instance.getInstance().getLibrary().changeSTA((String) args[0], (String) args[1], (String) args[2],
+                                       (String) args[3], pg);
                        forcePgDoneSent(pg);
                } else if ("EXIT".equals(command)) {
                        if (!rw) {
-                               throw new AccessDeniedException("EXIT", "",
-                                               "Read-Only remote library, cannot close it");
+                               throw new RemoteLibraryException(
+                                               "Read-Only remote library: EXIT", false);
                        }
 
-                       stop(0, false);
+                       stop(10000, false);
                }
 
                return null;
@@ -352,7 +333,9 @@ public class RemoteLibraryServer extends ServerObject {
        @Override
        protected void onError(Exception e) {
                if (e instanceof SSLException) {
-                       System.out.println("[Client connection refused (bad key)]");
+                       long now = System.currentTimeMillis();
+                       System.out.println(StringUtils.fromTime(now) + ": "
+                                       + "[Client connection refused (bad key)]");
                } else {
                        getTraceHandler().error(e);
                }
@@ -422,16 +405,19 @@ public class RemoteLibraryServer extends ServerObject {
         * @return TRUE if it was a progress event, FALSE if not
         */
        static boolean updateProgress(Progress pg, Object rep) {
-               if (rep instanceof Integer[]) {
-                       Integer[] a = (Integer[]) rep;
-                       if (a.length == 3) {
-                               int min = a[0];
-                               int max = a[1];
-                               int progress = a[2];
+               if (rep instanceof Object[]) {
+                       Object[] a = (Object[]) rep;
+                       if (a.length >= 3) {
+                               int min = (Integer)a[0];
+                               int max = (Integer)a[1];
+                               int progress = (Integer)a[2];
 
                                if (min >= 0 && min <= max) {
                                        pg.setMinMax(min, max);
                                        pg.setProgress(progress);
+                                       if (a.length >= 4) {
+                                               pg.put("meta", a[3]);
+                                       }
 
                                        return true;
                                }
@@ -460,27 +446,36 @@ public class RemoteLibraryServer extends ServerObject {
                };
 
                final Integer[] p = new Integer[] { -1, -1, -1 };
+               final Object[] pMeta = new MetaData[1];
                final Long[] lastTime = new Long[] { new Date().getTime() };
                pg.addProgressListener(new ProgressListener() {
                        @Override
                        public void progress(Progress progress, String name) {
+                               Object meta = pg.get("meta");
+                               if (meta instanceof MetaData) {
+                                       meta = removeCover((MetaData)meta);
+                               }
+                               
                                int min = pg.getMin();
                                int max = pg.getMax();
-                               int relativeProgress = min
+                               int rel = min
                                                + (int) Math.round(pg.getRelativeProgress()
                                                                * (max - min));
-
+                               
+                               boolean samePg = p[0] == min && p[1] == max && p[2] == rel;
+                               
                                // Do not re-send the same value twice over the wire,
                                // unless more than 2 seconds have elapsed (to maintain the
                                // connection)
-                               if ((p[0] != min || p[1] != max || p[2] != relativeProgress)
+                               if (!samePg || !same(pMeta[0], meta) //
                                                || (new Date().getTime() - lastTime[0] > 2000)) {
                                        p[0] = min;
                                        p[1] = max;
-                                       p[2] = relativeProgress;
+                                       p[2] = rel;
+                                       pMeta[0] = meta;
 
                                        try {
-                                               action.send(new Integer[] { min, max, relativeProgress });
+                                               action.send(new Object[] { min, max, rel, meta });
                                                action.rec();
                                        } catch (Exception e) {
                                                getTraceHandler().error(e);
@@ -495,6 +490,13 @@ public class RemoteLibraryServer extends ServerObject {
 
                return pg;
        }
+       
+       private boolean same(Object obj1, Object obj2) {
+               if (obj1 == null || obj2 == null)
+                       return obj1 == null && obj2 == null;
+
+               return obj1.equals(obj2);
+       }
 
        // with 30 seconds timeout
        private void forcePgDoneSent(Progress pg) {
@@ -508,4 +510,16 @@ public class RemoteLibraryServer extends ServerObject {
                        }
                }
        }
+       
+       private MetaData removeCover(MetaData meta) {
+               MetaData light;
+               if (meta.getCover() == null) {
+                       light = meta;
+               } else {
+                       light = meta.clone();
+                       light.setCover(null);
+               }
+               
+               return light;
+       }
 }