1 package be
.nikiroo
.fanfix
.library
;
4 import java
.io
.IOException
;
6 import java
.net
.UnknownHostException
;
7 import java
.util
.ArrayList
;
10 import javax
.net
.ssl
.SSLException
;
12 import be
.nikiroo
.fanfix
.Instance
;
13 import be
.nikiroo
.fanfix
.data
.MetaData
;
14 import be
.nikiroo
.fanfix
.data
.Story
;
15 import be
.nikiroo
.utils
.Image
;
16 import be
.nikiroo
.utils
.Progress
;
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 key
;
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
) {
49 public String
getLibraryName() {
50 return host
+ ":" + port
;
54 public Status
getStatus() {
55 final Status
[] result
= new Status
[1];
57 result
[0] = Status
.INVALID
;
60 Instance
.getTraceHandler().trace("Getting remote lib status...");
61 new ConnectActionClientObject(host
, port
, key
) {
63 public void action() throws Exception
{
64 Object rep
= send(new Object
[] { "PING" });
66 if ("PONG".equals(rep
)) {
67 result
[0] = Status
.READY
;
69 result
[0] = Status
.UNAUTORIZED
;
74 protected void onError(Exception e
) {
75 if (e
instanceof SSLException
) {
76 result
[0] = Status
.UNAUTORIZED
;
78 result
[0] = Status
.UNAVAILABLE
;
82 } catch (UnknownHostException e
) {
83 result
[0] = Status
.INVALID
;
84 } catch (IllegalArgumentException e
) {
85 result
[0] = Status
.INVALID
;
86 } catch (Exception e
) {
87 result
[0] = Status
.UNAVAILABLE
;
90 Instance
.getTraceHandler().trace("Remote lib status: " + result
[0]);
95 public Image
getCover(final String luid
) {
96 final Image
[] result
= new Image
[1];
99 new ConnectActionClientObject(host
, port
, key
) {
101 public void action() throws Exception
{
102 Object rep
= send(new Object
[] { "GET_COVER", luid
});
103 result
[0] = (Image
) rep
;
107 protected void onError(Exception e
) {
108 if (e
instanceof SSLException
) {
109 Instance
.getTraceHandler().error(
110 "Connection refused (bad key)");
112 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
, key
) {
140 public void action() throws Exception
{
141 Object rep
= send(new Object
[] { "GET_CUSTOM_COVER", type
,
143 result
[0] = (Image
) rep
;
147 protected void onError(Exception e
) {
148 if (e
instanceof SSLException
) {
149 Instance
.getTraceHandler().error(
150 "Connection refused (bad key)");
152 Instance
.getTraceHandler().error(e
);
156 } catch (Exception e
) {
157 Instance
.getTraceHandler().error(e
);
164 public synchronized Story
getStory(final String luid
, Progress pg
) {
165 final Progress pgF
= pg
;
166 final Story
[] result
= new Story
[1];
169 new ConnectActionClientObject(host
, port
, key
) {
171 public void action() throws Exception
{
177 Object rep
= send(new Object
[] { "GET_STORY", luid
});
179 MetaData meta
= null;
180 if (rep
instanceof MetaData
) {
181 meta
= (MetaData
) rep
;
182 if (meta
.getWords() <= Integer
.MAX_VALUE
) {
183 pg
.setMinMax(0, (int) meta
.getWords());
187 List
<Object
> list
= new ArrayList
<Object
>();
188 for (Object obj
= send(null); obj
!= null; obj
= send(null)) {
193 result
[0] = RemoteLibraryServer
.rebuildStory(list
);
198 protected void onError(Exception e
) {
199 if (e
instanceof SSLException
) {
200 Instance
.getTraceHandler().error(
201 "Connection refused (bad key)");
203 Instance
.getTraceHandler().error(e
);
207 } catch (Exception e
) {
208 Instance
.getTraceHandler().error(e
);
215 public synchronized Story
save(final Story story
, final String luid
,
216 Progress pg
) throws IOException
{
217 final String
[] luidSaved
= new String
[1];
218 Progress pgSave
= new Progress();
219 Progress pgRefresh
= new Progress();
225 pg
.addProgress(pgSave
, 9);
226 pg
.addProgress(pgRefresh
, 1);
228 final Progress pgF
= pgSave
;
230 new ConnectActionClientObject(host
, port
, key
) {
232 public void action() throws Exception
{
234 if (story
.getMeta().getWords() <= Integer
.MAX_VALUE
) {
235 pg
.setMinMax(0, (int) story
.getMeta().getWords());
238 send(new Object
[] { "SAVE_STORY", luid
});
240 List
<Object
> list
= RemoteLibraryServer
.breakStory(story
);
241 for (Object obj
: list
) {
246 luidSaved
[0] = (String
) send(null);
252 protected void onError(Exception e
) {
253 if (e
instanceof SSLException
) {
254 Instance
.getTraceHandler().error(
255 "Connection refused (bad key)");
257 Instance
.getTraceHandler().error(e
);
262 // because the meta changed:
263 MetaData meta
= getInfo(luidSaved
[0]);
264 if (story
.getMeta().getClass() != null) {
265 // If already available locally:
266 meta
.setCover(story
.getMeta().getCover());
269 meta
.setCover(getCover(meta
.getLuid()));
279 public synchronized void delete(final String luid
) throws IOException
{
280 new ConnectActionClientObject(host
, port
, key
) {
282 public void action() throws Exception
{
283 send(new Object
[] { "DELETE_STORY", luid
});
287 protected void onError(Exception e
) {
288 if (e
instanceof SSLException
) {
289 Instance
.getTraceHandler().error(
290 "Connection refused (bad key)");
292 Instance
.getTraceHandler().error(e
);
299 public void setSourceCover(final String source
, final String luid
) {
300 setCover(source
, luid
, "SOURCE");
304 public void setAuthorCover(final String author
, final String luid
) {
305 setCover(author
, luid
, "AUTHOR");
308 // type = "SOURCE" | "AUTHOR"
309 private void setCover(final String value
, final String luid
,
312 new ConnectActionClientObject(host
, port
, key
) {
314 public void action() throws Exception
{
315 send(new Object
[] { "SET_COVER", type
, value
, luid
});
319 protected void onError(Exception e
) {
320 if (e
instanceof SSLException
) {
321 Instance
.getTraceHandler().error(
322 "Connection refused (bad key)");
324 Instance
.getTraceHandler().error(e
);
328 } catch (IOException e
) {
329 Instance
.getTraceHandler().error(e
);
334 // Could work (more slowly) without it
335 public Story
imprt(final URL url
, Progress pg
) throws IOException
{
336 // Import the file locally if it is actually a file
337 if (url
== null || url
.getProtocol().equalsIgnoreCase("file")) {
338 return super.imprt(url
, pg
);
341 // Import it remotely if it is an URL
348 Progress pgImprt
= new Progress();
349 Progress pgGet
= new Progress();
350 pg
.addProgress(pgImprt
, 1);
351 pg
.addProgress(pgGet
, 1);
353 final Progress pgF
= pgImprt
;
354 final String
[] luid
= new String
[1];
357 new ConnectActionClientObject(host
, port
, key
) {
359 public void action() throws Exception
{
362 Object rep
= send(new Object
[] { "IMPORT", url
.toString() });
365 if (!RemoteLibraryServer
.updateProgress(pg
, rep
)) {
373 luid
[0] = (String
) rep
;
377 protected void onError(Exception e
) {
378 if (e
instanceof SSLException
) {
379 Instance
.getTraceHandler().error(
380 "Connection refused (bad key)");
382 Instance
.getTraceHandler().error(e
);
386 } catch (IOException e
) {
387 Instance
.getTraceHandler().error(e
);
390 if (luid
[0] == null) {
391 throw new IOException("Remote failure");
394 Story story
= getStory(luid
[0], pgGet
);
402 // Could work (more slowly) without it
403 protected synchronized void changeSTA(final String luid
,
404 final String newSource
, final String newTitle
,
405 final String newAuthor
, Progress pg
) throws IOException
{
406 final Progress pgF
= pg
== null ?
new Progress() : pg
;
409 new ConnectActionClientObject(host
, port
, key
) {
411 public void action() throws Exception
{
414 Object rep
= send(new Object
[] { "CHANGE_STA", luid
,
415 newSource
, newTitle
, newAuthor
});
417 if (!RemoteLibraryServer
.updateProgress(pg
, rep
)) {
426 protected void onError(Exception e
) {
427 if (e
instanceof SSLException
) {
428 Instance
.getTraceHandler().error(
429 "Connection refused (bad key)");
431 Instance
.getTraceHandler().error(e
);
435 } catch (IOException e
) {
436 Instance
.getTraceHandler().error(e
);
441 public synchronized File
getFile(final String luid
, Progress pg
) {
442 throw new java
.lang
.InternalError(
443 "Operation not supportorted on remote Libraries");
451 new ConnectActionClientObject(host
, port
, key
) {
453 public void action() throws Exception
{
454 send(new Object
[] { "EXIT" });
458 protected void onError(Exception e
) {
459 if (e
instanceof SSLException
) {
460 Instance
.getTraceHandler().error(
461 "Connection refused (bad key)");
463 Instance
.getTraceHandler().error(e
);
467 } catch (IOException e
) {
468 Instance
.getTraceHandler().error(e
);
473 public synchronized MetaData
getInfo(String luid
) {
474 List
<MetaData
> metas
= getMetasList(luid
, null);
475 if (!metas
.isEmpty()) {
483 protected List
<MetaData
> getMetas(Progress pg
) {
484 return getMetasList("*", pg
);
488 protected void updateInfo(MetaData meta
) {
489 // Will be taken care of directly server side
493 protected void invalidateInfo(String luid
) {
494 // Will be taken care of directly server side
497 // The following methods are only used by Save and Delete in BasicLibrary:
500 protected int getNextId() {
501 throw new java
.lang
.InternalError("Should not have been called");
505 protected void doDelete(String luid
) throws IOException
{
506 throw new java
.lang
.InternalError("Should not have been called");
510 protected Story
doSave(Story story
, Progress pg
) throws IOException
{
511 throw new java
.lang
.InternalError("Should not have been called");
517 * Return the meta of the given story or a list of all known metas if the
520 * Will not get the covers.
523 * the luid of the story or *
525 * the optional progress
530 private List
<MetaData
> getMetasList(final String luid
, Progress pg
) {
531 final Progress pgF
= pg
;
532 final List
<MetaData
> metas
= new ArrayList
<MetaData
>();
535 new ConnectActionClientObject(host
, port
, key
) {
537 public void action() throws Exception
{
543 Object rep
= send(new Object
[] { "GET_METADATA", luid
});
546 if (!RemoteLibraryServer
.updateProgress(pg
, rep
)) {
553 if (rep
instanceof MetaData
[]) {
554 for (MetaData meta
: (MetaData
[]) rep
) {
557 } else if (rep
!= null) {
558 metas
.add((MetaData
) rep
);
563 protected void onError(Exception e
) {
564 if (e
instanceof SSLException
) {
565 Instance
.getTraceHandler().error(
566 "Connection refused (bad key)");
568 Instance
.getTraceHandler().error(e
);
572 } catch (Exception e
) {
573 Instance
.getTraceHandler().error(e
);