1 package be
.nikiroo
.fanfix
.library
;
4 import java
.io
.IOException
;
6 import java
.net
.UnknownHostException
;
7 import java
.util
.ArrayList
;
10 import be
.nikiroo
.fanfix
.Instance
;
11 import be
.nikiroo
.fanfix
.data
.MetaData
;
12 import be
.nikiroo
.fanfix
.data
.Story
;
13 import be
.nikiroo
.utils
.Image
;
14 import be
.nikiroo
.utils
.Progress
;
15 import be
.nikiroo
.utils
.StringUtils
;
16 import be
.nikiroo
.utils
.Version
;
17 import be
.nikiroo
.utils
.serial
.server
.ConnectActionClientObject
;
20 * This {@link BasicLibrary} will access a remote server to list the available
21 * stories, and download the ones you try to load to the local directory
22 * specified in the configuration.
26 public class RemoteLibrary
extends BasicLibrary
{
29 private final String md5
;
32 * Create a {@link RemoteLibrary} linked to the given server.
35 * the key that will allow us to exchange information with the
38 * the host to contact or NULL for localhost
40 * the port to contact it on
42 public RemoteLibrary(String key
, String host
, int port
) {
43 this.md5
= StringUtils
.getMd5Hash(key
);
49 public String
getLibraryName() {
50 return host
+ ":" + port
;
54 public Status
getStatus() {
55 final Status
[] result
= new Status
[1];
57 result
[0] = Status
.INVALID
;
59 ConnectActionClientObject action
= null;
61 Instance
.getTraceHandler().trace("Getting remote lib status...");
62 action
= new ConnectActionClientObject(host
, port
, true) {
64 public void action(Version serverVersion
) throws Exception
{
65 Object rep
= send(new Object
[] { md5
, "PING" });
66 if ("PONG".equals(rep
)) {
67 result
[0] = Status
.READY
;
69 result
[0] = Status
.UNAUTORIZED
;
74 protected void onError(Exception e
) {
75 result
[0] = Status
.UNAVAILABLE
;
79 } catch (UnknownHostException e
) {
80 result
[0] = Status
.INVALID
;
81 } catch (IllegalArgumentException e
) {
82 result
[0] = Status
.INVALID
;
83 } catch (Exception e
) {
84 result
[0] = Status
.UNAVAILABLE
;
90 } catch (Exception e
) {
91 result
[0] = Status
.UNAVAILABLE
;
95 Instance
.getTraceHandler().trace("Remote lib status: " + result
[0]);
100 public Image
getCover(final String luid
) {
101 final Image
[] result
= new Image
[1];
104 new ConnectActionClientObject(host
, port
, true) {
106 public void action(Version serverVersion
) throws Exception
{
107 Object rep
= send(new Object
[] { md5
, "GET_COVER", luid
});
108 result
[0] = (Image
) rep
;
112 protected void onError(Exception e
) {
113 Instance
.getTraceHandler().error(e
);
116 } catch (Exception e
) {
117 Instance
.getTraceHandler().error(e
);
124 public Image
getCustomSourceCover(final String source
) {
125 return getCustomCover(source
, "SOURCE");
129 public Image
getCustomAuthorCover(final String author
) {
130 return getCustomCover(author
, "AUTHOR");
133 // type: "SOURCE" or "AUTHOR"
134 private Image
getCustomCover(final String source
, final String type
) {
135 final Image
[] result
= new Image
[1];
138 new ConnectActionClientObject(host
, port
, true) {
140 public void action(Version serverVersion
) throws Exception
{
141 Object rep
= send(new Object
[] { md5
, "GET_CUSTOM_COVER",
143 result
[0] = (Image
) rep
;
147 protected void onError(Exception e
) {
148 Instance
.getTraceHandler().error(e
);
151 } catch (Exception e
) {
152 Instance
.getTraceHandler().error(e
);
159 public synchronized Story
getStory(final String luid
, Progress pg
) {
160 final Progress pgF
= pg
;
161 final Story
[] result
= new Story
[1];
164 new ConnectActionClientObject(host
, port
, true) {
166 public void action(Version serverVersion
) throws Exception
{
172 Object rep
= send(new Object
[] { md5
, "GET_STORY", luid
});
174 MetaData meta
= null;
175 if (rep
instanceof MetaData
) {
176 meta
= (MetaData
) rep
;
177 if (meta
.getWords() <= Integer
.MAX_VALUE
) {
178 pg
.setMinMax(0, (int) meta
.getWords());
182 List
<Object
> list
= new ArrayList
<Object
>();
183 for (Object obj
= send(null); obj
!= null; obj
= send(null)) {
188 result
[0] = RemoteLibraryServer
.rebuildStory(list
);
193 protected void onError(Exception e
) {
194 Instance
.getTraceHandler().error(e
);
197 } catch (Exception e
) {
198 Instance
.getTraceHandler().error(e
);
205 public synchronized Story
save(final Story story
, final String luid
,
206 Progress pg
) throws IOException
{
207 final String
[] luidSaved
= new String
[1];
208 Progress pgSave
= new Progress();
209 Progress pgRefresh
= new Progress();
215 pg
.addProgress(pgSave
, 9);
216 pg
.addProgress(pgRefresh
, 1);
218 final Progress pgF
= pgSave
;
220 new ConnectActionClientObject(host
, port
, true) {
222 public void action(Version serverVersion
) throws Exception
{
224 if (story
.getMeta().getWords() <= Integer
.MAX_VALUE
) {
225 pg
.setMinMax(0, (int) story
.getMeta().getWords());
228 send(new Object
[] { md5
, "SAVE_STORY", luid
});
230 List
<Object
> list
= RemoteLibraryServer
.breakStory(story
);
231 for (Object obj
: list
) {
236 luidSaved
[0] = (String
) send(null);
242 protected void onError(Exception e
) {
243 Instance
.getTraceHandler().error(e
);
247 // because the meta changed:
248 MetaData meta
= getInfo(luidSaved
[0]);
249 if (story
.getMeta().getClass() != null) {
250 // If already available locally:
251 meta
.setCover(story
.getMeta().getCover());
254 meta
.setCover(getCover(meta
.getLuid()));
264 public synchronized void delete(final String luid
) throws IOException
{
265 new ConnectActionClientObject(host
, port
, true) {
267 public void action(Version serverVersion
) throws Exception
{
268 send(new Object
[] { md5
, "DELETE_STORY", luid
});
272 protected void onError(Exception e
) {
273 Instance
.getTraceHandler().error(e
);
279 public void setSourceCover(final String source
, final String luid
) {
280 setCover(source
, luid
, "SOURCE");
284 public void setAuthorCover(final String author
, final String luid
) {
285 setCover(author
, luid
, "AUTHOR");
288 // type = "SOURCE" | "AUTHOR"
289 private void setCover(final String value
, final String luid
,
292 new ConnectActionClientObject(host
, port
, true) {
294 public void action(Version serverVersion
) throws Exception
{
295 send(new Object
[] { md5
, "SET_COVER", type
, value
, luid
});
299 protected void onError(Exception e
) {
300 Instance
.getTraceHandler().error(e
);
303 } catch (IOException e
) {
304 Instance
.getTraceHandler().error(e
);
309 // Could work (more slowly) without it
310 public Story
imprt(final URL url
, Progress pg
) throws IOException
{
311 // Import the file locally if it is actually a file
312 if (url
== null || url
.getProtocol().equalsIgnoreCase("file")) {
313 return super.imprt(url
, pg
);
316 // Import it remotely if it is an URL
323 Progress pgImprt
= new Progress();
324 Progress pgGet
= new Progress();
325 pg
.addProgress(pgImprt
, 1);
326 pg
.addProgress(pgGet
, 1);
328 final Progress pgF
= pgImprt
;
329 final String
[] luid
= new String
[1];
332 new ConnectActionClientObject(host
, port
, true) {
334 public void action(Version serverVersion
) throws Exception
{
337 Object rep
= send(new Object
[] { md5
, "IMPORT",
341 if (!RemoteLibraryServer
.updateProgress(pg
, rep
)) {
349 luid
[0] = (String
) rep
;
353 protected void onError(Exception e
) {
354 Instance
.getTraceHandler().error(e
);
357 } catch (IOException e
) {
358 Instance
.getTraceHandler().error(e
);
361 if (luid
[0] == null) {
362 throw new IOException("Remote failure");
365 Story story
= getStory(luid
[0], pgGet
);
373 // Could work (more slowly) without it
374 protected synchronized void changeSTA(final String luid
,
375 final String newSource
, final String newTitle
,
376 final String newAuthor
, Progress pg
) throws IOException
{
377 final Progress pgF
= pg
== null ?
new Progress() : pg
;
380 new ConnectActionClientObject(host
, port
, true) {
382 public void action(Version serverVersion
) throws Exception
{
385 Object rep
= send(new Object
[] { md5
, "CHANGE_STA", luid
,
386 newSource
, newTitle
, newAuthor
});
388 if (!RemoteLibraryServer
.updateProgress(pg
, rep
)) {
397 protected void onError(Exception e
) {
398 Instance
.getTraceHandler().error(e
);
401 } catch (IOException e
) {
402 Instance
.getTraceHandler().error(e
);
407 public synchronized File
getFile(final String luid
, Progress pg
) {
408 throw new java
.lang
.InternalError(
409 "Operation not supportorted on remote Libraries");
417 new ConnectActionClientObject(host
, port
, true) {
419 public void action(Version serverVersion
) throws Exception
{
420 send(new Object
[] { md5
, "EXIT" });
424 protected void onError(Exception e
) {
425 Instance
.getTraceHandler().error(e
);
428 } catch (IOException e
) {
429 Instance
.getTraceHandler().error(e
);
434 public synchronized MetaData
getInfo(String luid
) {
435 List
<MetaData
> metas
= getMetasList(luid
, null);
436 if (!metas
.isEmpty()) {
444 protected List
<MetaData
> getMetas(Progress pg
) {
445 return getMetasList("*", pg
);
449 protected void updateInfo(MetaData meta
) {
450 // Will be taken care of directly server side
454 protected void invalidateInfo(String luid
) {
455 // Will be taken care of directly server side
458 // The following methods are only used by Save and Delete in BasicLibrary:
461 protected int getNextId() {
462 throw new java
.lang
.InternalError("Should not have been called");
466 protected void doDelete(String luid
) throws IOException
{
467 throw new java
.lang
.InternalError("Should not have been called");
471 protected Story
doSave(Story story
, Progress pg
) throws IOException
{
472 throw new java
.lang
.InternalError("Should not have been called");
478 * Return the meta of the given story or a list of all known metas if the
481 * Will not get the covers.
484 * the luid of the story or *
486 * the optional progress
491 private List
<MetaData
> getMetasList(final String luid
, Progress pg
) {
492 final Progress pgF
= pg
;
493 final List
<MetaData
> metas
= new ArrayList
<MetaData
>();
496 new ConnectActionClientObject(host
, port
, true) {
498 public void action(Version serverVersion
) throws Exception
{
504 Object rep
= send(new Object
[] { md5
, "GET_METADATA", luid
});
507 if (!RemoteLibraryServer
.updateProgress(pg
, rep
)) {
514 if (rep
instanceof MetaData
[]) {
515 for (MetaData meta
: (MetaData
[]) rep
) {
518 } else if (rep
!= null) {
519 metas
.add((MetaData
) rep
);
524 protected void onError(Exception e
) {
525 Instance
.getTraceHandler().error(e
);
528 } catch (Exception e
) {
529 Instance
.getTraceHandler().error(e
);