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
.Version
;
18 import be
.nikiroo
.utils
.serial
.server
.ConnectActionClientObject
;
21 * This {@link BasicLibrary} will access a remote server to list the available
22 * stories, and download the ones you try to load to the local directory
23 * specified in the configuration.
27 public class RemoteLibrary
extends BasicLibrary
{
30 private final String key
;
33 * Create a {@link RemoteLibrary} linked to the given server.
36 * the key that will allow us to exchange information with the
39 * the host to contact or NULL for localhost
41 * the port to contact it on
43 public RemoteLibrary(String key
, String host
, int port
) {
50 public String
getLibraryName() {
51 return host
+ ":" + port
;
55 public Status
getStatus() {
56 final Status
[] result
= new Status
[1];
58 result
[0] = Status
.INVALID
;
61 Instance
.getTraceHandler().trace("Getting remote lib status...");
62 new ConnectActionClientObject(host
, port
, key
) {
64 public void action(Version serverVersion
) throws Exception
{
65 Object rep
= send(new Object
[] { "PING" });
67 if ("PONG".equals(rep
)) {
68 result
[0] = Status
.READY
;
70 result
[0] = Status
.UNAUTORIZED
;
75 protected void onError(Exception e
) {
76 if (e
instanceof SSLException
) {
77 result
[0] = Status
.UNAUTORIZED
;
79 result
[0] = Status
.UNAVAILABLE
;
83 } catch (UnknownHostException e
) {
84 result
[0] = Status
.INVALID
;
85 } catch (IllegalArgumentException e
) {
86 result
[0] = Status
.INVALID
;
87 } catch (Exception e
) {
88 result
[0] = Status
.UNAVAILABLE
;
91 Instance
.getTraceHandler().trace("Remote lib status: " + result
[0]);
96 public Image
getCover(final String luid
) {
97 final Image
[] result
= new Image
[1];
100 new ConnectActionClientObject(host
, port
, key
) {
102 public void action(Version serverVersion
) throws Exception
{
103 Object rep
= send(new Object
[] { "GET_COVER", luid
});
104 result
[0] = (Image
) rep
;
108 protected void onError(Exception e
) {
109 if (e
instanceof SSLException
) {
110 Instance
.getTraceHandler().error(
111 "Connection refused (bad key)");
113 Instance
.getTraceHandler().error(e
);
117 } catch (Exception e
) {
118 Instance
.getTraceHandler().error(e
);
125 public Image
getCustomSourceCover(final String source
) {
126 return getCustomCover(source
, "SOURCE");
130 public Image
getCustomAuthorCover(final String author
) {
131 return getCustomCover(author
, "AUTHOR");
134 // type: "SOURCE" or "AUTHOR"
135 private Image
getCustomCover(final String source
, final String type
) {
136 final Image
[] result
= new Image
[1];
139 new ConnectActionClientObject(host
, port
, key
) {
141 public void action(Version serverVersion
) throws Exception
{
142 Object rep
= send(new Object
[] { "GET_CUSTOM_COVER", type
,
144 result
[0] = (Image
) rep
;
148 protected void onError(Exception e
) {
149 if (e
instanceof SSLException
) {
150 Instance
.getTraceHandler().error(
151 "Connection refused (bad key)");
153 Instance
.getTraceHandler().error(e
);
157 } catch (Exception e
) {
158 Instance
.getTraceHandler().error(e
);
165 public synchronized Story
getStory(final String luid
, Progress pg
) {
166 final Progress pgF
= pg
;
167 final Story
[] result
= new Story
[1];
170 new ConnectActionClientObject(host
, port
, key
) {
172 public void action(Version serverVersion
) throws Exception
{
178 Object rep
= send(new Object
[] { "GET_STORY", luid
});
180 MetaData meta
= null;
181 if (rep
instanceof MetaData
) {
182 meta
= (MetaData
) rep
;
183 if (meta
.getWords() <= Integer
.MAX_VALUE
) {
184 pg
.setMinMax(0, (int) meta
.getWords());
188 List
<Object
> list
= new ArrayList
<Object
>();
189 for (Object obj
= send(null); obj
!= null; obj
= send(null)) {
194 result
[0] = RemoteLibraryServer
.rebuildStory(list
);
199 protected void onError(Exception e
) {
200 if (e
instanceof SSLException
) {
201 Instance
.getTraceHandler().error(
202 "Connection refused (bad key)");
204 Instance
.getTraceHandler().error(e
);
208 } catch (Exception e
) {
209 Instance
.getTraceHandler().error(e
);
216 public synchronized Story
save(final Story story
, final String luid
,
217 Progress pg
) throws IOException
{
218 final String
[] luidSaved
= new String
[1];
219 Progress pgSave
= new Progress();
220 Progress pgRefresh
= new Progress();
226 pg
.addProgress(pgSave
, 9);
227 pg
.addProgress(pgRefresh
, 1);
229 final Progress pgF
= pgSave
;
231 new ConnectActionClientObject(host
, port
, key
) {
233 public void action(Version serverVersion
) throws Exception
{
235 if (story
.getMeta().getWords() <= Integer
.MAX_VALUE
) {
236 pg
.setMinMax(0, (int) story
.getMeta().getWords());
239 send(new Object
[] { "SAVE_STORY", luid
});
241 List
<Object
> list
= RemoteLibraryServer
.breakStory(story
);
242 for (Object obj
: list
) {
247 luidSaved
[0] = (String
) send(null);
253 protected void onError(Exception e
) {
254 if (e
instanceof SSLException
) {
255 Instance
.getTraceHandler().error(
256 "Connection refused (bad key)");
258 Instance
.getTraceHandler().error(e
);
263 // because the meta changed:
264 MetaData meta
= getInfo(luidSaved
[0]);
265 if (story
.getMeta().getClass() != null) {
266 // If already available locally:
267 meta
.setCover(story
.getMeta().getCover());
270 meta
.setCover(getCover(meta
.getLuid()));
280 public synchronized void delete(final String luid
) throws IOException
{
281 new ConnectActionClientObject(host
, port
, key
) {
283 public void action(Version serverVersion
) throws Exception
{
284 send(new Object
[] { "DELETE_STORY", luid
});
288 protected void onError(Exception e
) {
289 if (e
instanceof SSLException
) {
290 Instance
.getTraceHandler().error(
291 "Connection refused (bad key)");
293 Instance
.getTraceHandler().error(e
);
300 public void setSourceCover(final String source
, final String luid
) {
301 setCover(source
, luid
, "SOURCE");
305 public void setAuthorCover(final String author
, final String luid
) {
306 setCover(author
, luid
, "AUTHOR");
309 // type = "SOURCE" | "AUTHOR"
310 private void setCover(final String value
, final String luid
,
313 new ConnectActionClientObject(host
, port
, key
) {
315 public void action(Version serverVersion
) throws Exception
{
316 send(new Object
[] { "SET_COVER", type
, value
, luid
});
320 protected void onError(Exception e
) {
321 if (e
instanceof SSLException
) {
322 Instance
.getTraceHandler().error(
323 "Connection refused (bad key)");
325 Instance
.getTraceHandler().error(e
);
329 } catch (IOException e
) {
330 Instance
.getTraceHandler().error(e
);
335 // Could work (more slowly) without it
336 public Story
imprt(final URL url
, Progress pg
) throws IOException
{
337 // Import the file locally if it is actually a file
338 if (url
== null || url
.getProtocol().equalsIgnoreCase("file")) {
339 return super.imprt(url
, pg
);
342 // Import it remotely if it is an URL
349 Progress pgImprt
= new Progress();
350 Progress pgGet
= new Progress();
351 pg
.addProgress(pgImprt
, 1);
352 pg
.addProgress(pgGet
, 1);
354 final Progress pgF
= pgImprt
;
355 final String
[] luid
= new String
[1];
358 new ConnectActionClientObject(host
, port
, key
) {
360 public void action(Version serverVersion
) throws Exception
{
363 Object rep
= send(new Object
[] { "IMPORT", url
.toString() });
366 if (!RemoteLibraryServer
.updateProgress(pg
, rep
)) {
374 luid
[0] = (String
) rep
;
378 protected void onError(Exception e
) {
379 if (e
instanceof SSLException
) {
380 Instance
.getTraceHandler().error(
381 "Connection refused (bad key)");
383 Instance
.getTraceHandler().error(e
);
387 } catch (IOException e
) {
388 Instance
.getTraceHandler().error(e
);
391 if (luid
[0] == null) {
392 throw new IOException("Remote failure");
395 Story story
= getStory(luid
[0], pgGet
);
403 // Could work (more slowly) without it
404 protected synchronized void changeSTA(final String luid
,
405 final String newSource
, final String newTitle
,
406 final String newAuthor
, Progress pg
) throws IOException
{
407 final Progress pgF
= pg
== null ?
new Progress() : pg
;
410 new ConnectActionClientObject(host
, port
, key
) {
412 public void action(Version serverVersion
) throws Exception
{
415 Object rep
= send(new Object
[] { "CHANGE_STA", luid
,
416 newSource
, newTitle
, newAuthor
});
418 if (!RemoteLibraryServer
.updateProgress(pg
, rep
)) {
427 protected void onError(Exception e
) {
428 if (e
instanceof SSLException
) {
429 Instance
.getTraceHandler().error(
430 "Connection refused (bad key)");
432 Instance
.getTraceHandler().error(e
);
436 } catch (IOException e
) {
437 Instance
.getTraceHandler().error(e
);
442 public synchronized File
getFile(final String luid
, Progress pg
) {
443 throw new java
.lang
.InternalError(
444 "Operation not supportorted on remote Libraries");
452 new ConnectActionClientObject(host
, port
, key
) {
454 public void action(Version serverVersion
) throws Exception
{
455 send(new Object
[] { "EXIT" });
459 protected void onError(Exception e
) {
460 if (e
instanceof SSLException
) {
461 Instance
.getTraceHandler().error(
462 "Connection refused (bad key)");
464 Instance
.getTraceHandler().error(e
);
468 } catch (IOException e
) {
469 Instance
.getTraceHandler().error(e
);
474 public synchronized MetaData
getInfo(String luid
) {
475 List
<MetaData
> metas
= getMetasList(luid
, null);
476 if (!metas
.isEmpty()) {
484 protected List
<MetaData
> getMetas(Progress pg
) {
485 return getMetasList("*", pg
);
489 protected void updateInfo(MetaData meta
) {
490 // Will be taken care of directly server side
494 protected void invalidateInfo(String luid
) {
495 // Will be taken care of directly server side
498 // The following methods are only used by Save and Delete in BasicLibrary:
501 protected int getNextId() {
502 throw new java
.lang
.InternalError("Should not have been called");
506 protected void doDelete(String luid
) throws IOException
{
507 throw new java
.lang
.InternalError("Should not have been called");
511 protected Story
doSave(Story story
, Progress pg
) throws IOException
{
512 throw new java
.lang
.InternalError("Should not have been called");
518 * Return the meta of the given story or a list of all known metas if the
521 * Will not get the covers.
524 * the luid of the story or *
526 * the optional progress
531 private List
<MetaData
> getMetasList(final String luid
, Progress pg
) {
532 final Progress pgF
= pg
;
533 final List
<MetaData
> metas
= new ArrayList
<MetaData
>();
536 new ConnectActionClientObject(host
, port
, key
) {
538 public void action(Version serverVersion
) throws Exception
{
544 Object rep
= send(new Object
[] { "GET_METADATA", luid
});
547 if (!RemoteLibraryServer
.updateProgress(pg
, rep
)) {
554 if (rep
instanceof MetaData
[]) {
555 for (MetaData meta
: (MetaData
[]) rep
) {
558 } else if (rep
!= null) {
559 metas
.add((MetaData
) rep
);
564 protected void onError(Exception e
) {
565 if (e
instanceof SSLException
) {
566 Instance
.getTraceHandler().error(
567 "Connection refused (bad key)");
569 Instance
.getTraceHandler().error(e
);
573 } catch (Exception e
) {
574 Instance
.getTraceHandler().error(e
);