import be.nikiroo.fanfix.Instance;
import be.nikiroo.fanfix.data.MetaData;
import be.nikiroo.fanfix.data.Story;
-import be.nikiroo.fanfix.output.BasicOutput.OutputType;
import be.nikiroo.utils.Progress;
import be.nikiroo.utils.Version;
-import be.nikiroo.utils.serial.ConnectActionClient;
+import be.nikiroo.utils.serial.server.ConnectActionClientObject;
/**
* This {@link BasicLibrary} will access a remote server to list the available
- * stories, and download the one you try to load to the local directory
+ * stories, and download the ones you try to load to the local directory
* specified in the configuration.
*
* @author niki
public class RemoteLibrary extends BasicLibrary {
private String host;
private int port;
- private File baseDir;
-
- private LocalLibrary lib;
- private List<MetaData> metas;
+ private final String key;
/**
* Create a {@link RemoteLibrary} linked to the given server.
*
+ * @param key
+ * the key that will allow us to exchange information with the
+ * server
* @param host
* the host to contact or NULL for localhost
* @param port
* the port to contact it on
*/
- public RemoteLibrary(String host, int port) {
+ public RemoteLibrary(String key, String host, int port) {
+ this.key = key;
this.host = host;
this.port = port;
+ }
- this.baseDir = Instance.getRemoteDir(host);
- this.baseDir.mkdirs();
-
- this.lib = new LocalLibrary(baseDir, OutputType.INFO_TEXT,
- OutputType.CBZ);
+ @Override
+ public String getLibraryName() {
+ return host + ":" + port;
}
@Override
protected List<MetaData> getMetas(Progress pg) {
// TODO: progress
+ final List<MetaData> metas = new ArrayList<MetaData>();
+ MetaData[] fromNetwork = this.getRemoteObject( //
+ new Object[] { key, "GET_METADATA", "*" });
- if (metas == null) {
- metas = new ArrayList<MetaData>();
-
- try {
- new ConnectActionClient(host, port, true, null) {
- public void action(Version serverVersion) throws Exception {
- try {
- Object rep = send("GET_METADATA *");
- for (MetaData meta : (MetaData[]) rep) {
- metas.add(meta);
- }
- } catch (Exception e) {
- Instance.syserr(e);
- }
- }
- }.connect();
- } catch (IOException e) {
- Instance.syserr(e);
+ if (fromNetwork != null) {
+ for (MetaData meta : fromNetwork) {
+ metas.add(meta);
}
}
}
@Override
- public synchronized File getFile(final String luid) {
- File file = lib.getFile(luid);
- if (file == null) {
- final File[] tmp = new File[1];
- try {
- new ConnectActionClient(host, port, true, null) {
- public void action(Version serverVersion) throws Exception {
- try {
- Object rep = send("GET_STORY " + luid);
- Story story = (Story) rep;
- if (story != null) {
- lib.save(story, luid, null);
- tmp[0] = lib.getFile(luid);
- }
- } catch (Exception e) {
- Instance.syserr(e);
- }
- }
- }.connect();
- } catch (IOException e) {
- Instance.syserr(e);
- }
-
- file = tmp[0];
- }
-
- if (file != null) {
- MetaData meta = getInfo(luid);
- metas.add(meta);
- }
-
- return file;
+ public BufferedImage getCover(final String luid) {
+ return this.getRemoteObject( //
+ new Object[] { key, "GET_COVER", luid });
}
@Override
- public BufferedImage getCover(String luid) {
- // Retrieve it from the network if needed:
- if (lib.getInfo(luid) == null) {
- getFile(luid);
- }
+ public BufferedImage getSourceCover(final String source) {
+ return this.getRemoteObject( //
+ new Object[] { key, "GET_SOURCE_COVER", source });
+ }
- return lib.getCover(luid);
+ @Override
+ public synchronized Story getStory(final String luid, Progress pg) {
+ return this.getRemoteStory( //
+ new Object[] { key, "GET_STORY", luid });
}
@Override
protected void clearCache() {
- metas = null;
- lib.clearCache();
}
@Override
public synchronized Story save(Story story, String luid, Progress pg)
throws IOException {
+ getRemoteObject(new Object[] { key, "SAVE_STORY", story, luid });
+
+ // because the meta changed:
+ clearCache();
+ story.setMeta(getInfo(luid));
+
+ return story;
+ }
+
+ @Override
+ public synchronized void delete(String luid) throws IOException {
+ getRemoteObject(new Object[] { key, "DELETE_STORY", luid });
+ }
+
+ @Override
+ public void setSourceCover(String source, String luid) {
+ this.<BufferedImage> getRemoteObject( //
+ new Object[] { key, "SET_SOURCE_COVER", source, luid });
+ }
+
+ @Override
+ public synchronized File getFile(final String luid, Progress pg) {
throw new java.lang.InternalError(
- "No write support allowed on remote Libraries");
+ "Operation not supportorted on remote Libraries");
}
+ // The following methods are only used by Save and Delete in BasicLibrary:
+
@Override
protected int getNextId() {
- throw new java.lang.InternalError(
- "No write support allowed on remote Libraries");
+ throw new java.lang.InternalError("Should not have been called");
}
@Override
protected void doDelete(String luid) throws IOException {
- throw new java.lang.InternalError(
- "No write support allowed on remote Libraries");
+ throw new java.lang.InternalError("Should not have been called");
}
@Override
protected Story doSave(Story story, Progress pg) throws IOException {
- throw new java.lang.InternalError(
- "No write support allowed on remote Libraries");
+ throw new java.lang.InternalError("Should not have been called");
+ }
+
+ /**
+ * Return an object from the server.
+ *
+ * @param <T>
+ * the expected type of object
+ * @param command
+ * the command to send (can contain at most ONE {@link Story})
+ *
+ * @return the object or NULL
+ */
+ private <T> T getRemoteObject(final Object[] command) {
+ return getRemoteObjectOrStory(command, false);
+ }
+
+ /**
+ * Return an object from the server.
+ *
+ * @param command
+ * the command to send (can contain at most ONE {@link Story})
+ *
+ * @return the object or NULL
+ */
+ private Story getRemoteStory(final Object[] command) {
+ return getRemoteObjectOrStory(command, true);
+ }
+
+ /**
+ * Return an object from the server.
+ *
+ * @param <T>
+ * the expected type of object
+ * @param command
+ * the command to send (can contain at most ONE {@link Story})
+ *
+ * @return the object or NULL
+ */
+ @SuppressWarnings("unchecked")
+ private <T> T getRemoteObjectOrStory(final Object[] command,
+ final boolean getStory) {
+ final Object[] result = new Object[1];
+ try {
+ new ConnectActionClientObject(host, port, true) {
+ @Override
+ public void action(Version serverVersion) throws Exception {
+ try {
+ Story story = null;
+ for (int i = 0; i < command.length; i++) {
+ if (command[i] instanceof Story) {
+ story = (Story) command[i];
+ command[i] = null;
+ }
+ }
+
+ Object rep = send(command);
+
+ if (story != null) {
+ RemoteLibraryServer.sendStory(story, this);
+ }
+
+ if (getStory) {
+ rep = RemoteLibraryServer.recStory(this);
+ }
+
+ result[0] = rep;
+ } catch (Exception e) {
+ Instance.getTraceHandler().error(e);
+ }
+ }
+ }.connect();
+ } catch (IOException e) {
+ Instance.getTraceHandler().error(e);
+ }
+
+ try {
+ return (T) result[0];
+ } catch (Exception e) {
+ Instance.getTraceHandler().error(e);
+ return null;
+ }
}
}