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 action
= new ConnectActionClientObject(host
, port
, true) {
63 public void action(Version serverVersion
) throws Exception
{
64 Object rep
= send(new Object
[] { md5
, "PING" });
65 if ("PONG".equals(rep
)) {
66 result
[0] = Status
.READY
;
68 result
[0] = Status
.UNAUTORIZED
;
73 protected void onError(Exception e
) {
74 result
[0] = Status
.UNAVAILABLE
;
78 } catch (UnknownHostException e
) {
79 result
[0] = Status
.INVALID
;
80 } catch (IllegalArgumentException e
) {
81 result
[0] = Status
.INVALID
;
82 } catch (Exception e
) {
83 result
[0] = Status
.UNAVAILABLE
;
89 } catch (Exception e
) {
90 result
[0] = Status
.UNAVAILABLE
;
98 public Image
getCover(final String luid
) {
99 final Image
[] result
= new Image
[1];
102 new ConnectActionClientObject(host
, port
, true) {
104 public void action(Version serverVersion
) throws Exception
{
105 Object rep
= send(new Object
[] { md5
, "GET_COVER", luid
});
106 result
[0] = (Image
) rep
;
110 protected void onError(Exception e
) {
111 Instance
.getTraceHandler().error(e
);
114 } catch (Exception e
) {
115 Instance
.getTraceHandler().error(e
);
122 public Image
getCustomSourceCover(final String source
) {
123 final Image
[] result
= new Image
[1];
126 new ConnectActionClientObject(host
, port
, true) {
128 public void action(Version serverVersion
) throws Exception
{
129 Object rep
= send(new Object
[] { md5
,
130 "GET_CUSTOM_SOURCE_COVER", source
});
131 result
[0] = (Image
) rep
;
135 protected void onError(Exception e
) {
136 Instance
.getTraceHandler().error(e
);
139 } catch (Exception e
) {
140 Instance
.getTraceHandler().error(e
);
147 public synchronized Story
getStory(final String luid
, Progress pg
) {
148 final Progress pgF
= pg
;
149 final Story
[] result
= new Story
[1];
152 new ConnectActionClientObject(host
, port
, true) {
154 public void action(Version serverVersion
) throws Exception
{
160 Object rep
= send(new Object
[] { md5
, "GET_STORY", luid
});
162 MetaData meta
= null;
163 if (rep
instanceof MetaData
) {
164 meta
= (MetaData
) rep
;
165 if (meta
.getWords() <= Integer
.MAX_VALUE
) {
166 pg
.setMinMax(0, (int) meta
.getWords());
170 List
<Object
> list
= new ArrayList
<Object
>();
171 for (Object obj
= send(null); obj
!= null; obj
= send(null)) {
176 result
[0] = RemoteLibraryServer
.rebuildStory(list
);
181 protected void onError(Exception e
) {
182 Instance
.getTraceHandler().error(e
);
185 } catch (Exception e
) {
186 Instance
.getTraceHandler().error(e
);
193 public synchronized Story
save(final Story story
, final String luid
,
194 Progress pg
) throws IOException
{
195 final String
[] luidSaved
= new String
[1];
196 Progress pgSave
= new Progress();
197 Progress pgRefresh
= new Progress();
203 pg
.addProgress(pgSave
, 9);
204 pg
.addProgress(pgRefresh
, 1);
206 final Progress pgF
= pgSave
;
208 new ConnectActionClientObject(host
, port
, true) {
210 public void action(Version serverVersion
) throws Exception
{
212 if (story
.getMeta().getWords() <= Integer
.MAX_VALUE
) {
213 pg
.setMinMax(0, (int) story
.getMeta().getWords());
216 send(new Object
[] { md5
, "SAVE_STORY", luid
});
218 List
<Object
> list
= RemoteLibraryServer
.breakStory(story
);
219 for (Object obj
: list
) {
224 luidSaved
[0] = (String
) send(null);
230 protected void onError(Exception e
) {
231 Instance
.getTraceHandler().error(e
);
235 // because the meta changed:
236 MetaData meta
= getInfo(luidSaved
[0]);
237 if (story
.getMeta().getClass() != null) {
238 // If already available locally:
239 meta
.setCover(story
.getMeta().getCover());
242 meta
.setCover(getCover(meta
.getLuid()));
252 public synchronized void delete(final String luid
) throws IOException
{
253 new ConnectActionClientObject(host
, port
, true) {
255 public void action(Version serverVersion
) throws Exception
{
256 send(new Object
[] { md5
, "DELETE_STORY", luid
});
260 protected void onError(Exception e
) {
261 Instance
.getTraceHandler().error(e
);
267 public void setSourceCover(final String source
, final String luid
) {
269 new ConnectActionClientObject(host
, port
, true) {
271 public void action(Version serverVersion
) throws Exception
{
272 send(new Object
[] { md5
, "SET_SOURCE_COVER", source
, luid
});
276 protected void onError(Exception e
) {
277 Instance
.getTraceHandler().error(e
);
280 } catch (IOException e
) {
281 Instance
.getTraceHandler().error(e
);
286 // Could work (more slowly) without it
287 public Story
imprt(final URL url
, Progress pg
) throws IOException
{
288 // Import the file locally if it is actually a file
289 if (url
== null || url
.getProtocol().equalsIgnoreCase("file")) {
290 return super.imprt(url
, pg
);
293 // Import it remotely if it is an URL
300 Progress pgImprt
= new Progress();
301 Progress pgGet
= new Progress();
302 pg
.addProgress(pgImprt
, 1);
303 pg
.addProgress(pgGet
, 1);
305 final Progress pgF
= pgImprt
;
306 final String
[] luid
= new String
[1];
309 new ConnectActionClientObject(host
, port
, true) {
311 public void action(Version serverVersion
) throws Exception
{
314 Object rep
= send(new Object
[] { md5
, "IMPORT",
318 if (!RemoteLibraryServer
.updateProgress(pg
, rep
)) {
326 luid
[0] = (String
) rep
;
330 protected void onError(Exception e
) {
331 Instance
.getTraceHandler().error(e
);
334 } catch (IOException e
) {
335 Instance
.getTraceHandler().error(e
);
338 if (luid
[0] == null) {
339 throw new IOException("Remote failure");
342 Story story
= getStory(luid
[0], pgGet
);
350 // Could work (more slowly) without it
351 public synchronized void changeSource(final String luid
,
352 final String newSource
, Progress pg
) throws IOException
{
353 final Progress pgF
= pg
== null ?
new Progress() : pg
;
356 new ConnectActionClientObject(host
, port
, true) {
358 public void action(Version serverVersion
) throws Exception
{
361 Object rep
= send(new Object
[] { md5
, "CHANGE_SOURCE",
364 if (!RemoteLibraryServer
.updateProgress(pg
, rep
)) {
373 protected void onError(Exception e
) {
374 Instance
.getTraceHandler().error(e
);
377 } catch (IOException e
) {
378 Instance
.getTraceHandler().error(e
);
383 public synchronized File
getFile(final String luid
, Progress pg
) {
384 throw new java
.lang
.InternalError(
385 "Operation not supportorted on remote Libraries");
393 new ConnectActionClientObject(host
, port
, true) {
395 public void action(Version serverVersion
) throws Exception
{
396 send(new Object
[] { md5
, "EXIT" });
400 protected void onError(Exception e
) {
401 Instance
.getTraceHandler().error(e
);
404 } catch (IOException e
) {
405 Instance
.getTraceHandler().error(e
);
410 public synchronized MetaData
getInfo(String luid
) {
411 List
<MetaData
> metas
= getMetasList(luid
, null);
412 if (!metas
.isEmpty()) {
420 protected List
<MetaData
> getMetas(Progress pg
) {
421 return getMetasList("*", pg
);
425 protected void updateInfo(MetaData meta
) {
426 // Will be taken care of directly server side
430 protected void deleteInfo(String luid
) {
431 // Will be taken care of directly server side
434 // The following methods are only used by Save and Delete in BasicLibrary:
437 protected int getNextId() {
438 throw new java
.lang
.InternalError("Should not have been called");
442 protected void doDelete(String luid
) throws IOException
{
443 throw new java
.lang
.InternalError("Should not have been called");
447 protected Story
doSave(Story story
, Progress pg
) throws IOException
{
448 throw new java
.lang
.InternalError("Should not have been called");
454 * Return the meta of the given story or a list of all known metas if the
457 * Will not get the covers.
460 * the luid of the story or *
462 * the optional progress
467 private List
<MetaData
> getMetasList(final String luid
, Progress pg
) {
468 final Progress pgF
= pg
;
469 final List
<MetaData
> metas
= new ArrayList
<MetaData
>();
472 new ConnectActionClientObject(host
, port
, true) {
474 public void action(Version serverVersion
) throws Exception
{
480 Object rep
= send(new Object
[] { md5
, "GET_METADATA", luid
});
483 if (!RemoteLibraryServer
.updateProgress(pg
, rep
)) {
490 if (rep
instanceof MetaData
[]) {
491 for (MetaData meta
: (MetaData
[]) rep
) {
494 } else if (rep
!= null) {
495 metas
.add((MetaData
) rep
);
500 protected void onError(Exception e
) {
501 Instance
.getTraceHandler().error(e
);
504 } catch (Exception e
) {
505 Instance
.getTraceHandler().error(e
);