Try to fix the remote story sending again + traces
[nikiroo-utils.git] / src / be / nikiroo / fanfix / library / RemoteLibraryServer.java
CommitLineData
e42573a0 1package be.nikiroo.fanfix.library;
b0e88ebd 2
b0e88ebd 3import java.io.IOException;
085a2f9a 4import java.security.InvalidParameterException;
74a40dfb 5import java.util.ArrayList;
68e2c6d2 6import java.util.List;
b0e88ebd 7
e42573a0 8import be.nikiroo.fanfix.Instance;
74a40dfb 9import be.nikiroo.fanfix.data.Chapter;
b0e88ebd 10import be.nikiroo.fanfix.data.MetaData;
74a40dfb 11import be.nikiroo.fanfix.data.Paragraph;
085a2f9a 12import be.nikiroo.fanfix.data.Story;
b0e88ebd 13import be.nikiroo.utils.Version;
74a40dfb 14import be.nikiroo.utils.serial.server.ConnectActionClientObject;
62c63b07
NR
15import be.nikiroo.utils.serial.server.ConnectActionServerObject;
16import be.nikiroo.utils.serial.server.ServerObject;
b0e88ebd 17
a85e8077
NR
18/**
19 * Create a new remote server that will listen for order on the given port.
20 * <p>
2a25f781
NR
21 * The available commands are given as arrays of objects (first item is the key,
22 * second is the command, the rest are the arguments).
23 * <p>
24 * The key is always a String, the commands are also Strings; the parameters
25 * vary depending upon the command.
a85e8077 26 * <ul>
2a25f781 27 * <li>[key] GET_METADATA *: will return the metadata of all the stories in the
085a2f9a 28 * library</li>
2a25f781 29 * <li>[key] GET_STORY [luid]: will return the given story if it exists (or NULL
2070ced5 30 * if not)</li>
74a40dfb
NR
31 * <li>[key] SAVE_STORY [luid]: save the story (that must be sent just after the
32 * command) with the given LUID</li>
2a25f781
NR
33 * <li>[key] DELETE_STORY [luid]: delete the story of LUID luid</li>
34 * <li>[key] GET_COVER [luid]: return the cover of the story</li>
35 * <li>[key] GET_SOURCE_COVER [source]: return the cover for this source</li>
36 * <li>[key] SET_SOURCE_COVER [source], [luid]: set the default cover for the
2070ced5 37 * given source to the cover of the story denoted by luid</li>
2a25f781 38 * <li>[key] EXIT: stop the server</li>
a85e8077
NR
39 * </ul>
40 *
41 * @author niki
42 */
62c63b07 43public class RemoteLibraryServer extends ServerObject {
2070ced5 44 private final String key;
b0e88ebd 45
a85e8077
NR
46 /**
47 * Create a new remote server (will not be active until
48 * {@link RemoteLibraryServer#start()} is called).
49 *
2070ced5
NR
50 * @param key
51 * the key that will restrict access to this server
a85e8077
NR
52 * @param port
53 * the port to listen on
54 *
55 * @throws IOException
56 * in case of I/O error
57 */
2070ced5 58 public RemoteLibraryServer(String key, int port) throws IOException {
22b2b942 59 super("Fanfix remote library", port, true);
2070ced5 60 this.key = key;
b0e88ebd
NR
61 }
62
63 @Override
62c63b07 64 protected Object onRequest(ConnectActionServerObject action,
b0e88ebd 65 Version clientVersion, Object data) throws Exception {
2070ced5 66 String key = "";
085a2f9a
NR
67 String command = "";
68 Object[] args = new Object[0];
69 if (data instanceof Object[]) {
2070ced5
NR
70 Object[] dataArray = (Object[]) data;
71 if (dataArray.length >= 2) {
72 args = new Object[dataArray.length - 2];
73 for (int i = 2; i < dataArray.length; i++) {
f569d249 74 args[i - 2] = dataArray[i];
2070ced5
NR
75 }
76
77 key = "" + dataArray[0];
78 command = "" + dataArray[1];
b0e88ebd
NR
79 }
80 }
81
2070ced5 82 System.out.print("[" + command + "] ");
085a2f9a
NR
83 for (Object arg : args) {
84 System.out.print(arg + " ");
85 }
86 System.out.println("");
b0e88ebd 87
2070ced5
NR
88 if (!key.equals(this.key)) {
89 System.out.println("Key rejected.");
90 throw new SecurityException("Invalid key");
91 }
92
a85e8077
NR
93 // TODO: progress (+send name + %age info back to client)
94
95 if ("GET_METADATA".equals(command)) {
2070ced5 96 if (args[0].equals("*")) {
a85e8077
NR
97 List<MetaData> metas = Instance.getLibrary().getMetas(null);
98 return metas.toArray(new MetaData[] {});
99 }
085a2f9a 100 throw new InvalidParameterException(
2070ced5 101 "only * is valid here, but you passed: " + args[0]);
a85e8077 102 } else if ("GET_STORY".equals(command)) {
74a40dfb
NR
103 Story story = Instance.getLibrary().getStory("" + args[0], null);
104 sendStory(story, action);
085a2f9a 105 } else if ("SAVE_STORY".equals(command)) {
74a40dfb
NR
106 Story story = recStory(action);
107 Instance.getLibrary().save(story, "" + args[1], null);
085a2f9a 108 } else if ("DELETE_STORY".equals(command)) {
2070ced5 109 Instance.getLibrary().delete("" + args[0]);
e604986c 110 } else if ("GET_COVER".equals(command)) {
2070ced5 111 return Instance.getLibrary().getCover("" + args[0]);
085a2f9a 112 } else if ("GET_SOURCE_COVER".equals(command)) {
2070ced5 113 return Instance.getLibrary().getSourceCover("" + args[0]);
085a2f9a 114 } else if ("SET_SOURCE_COVER".equals(command)) {
2070ced5 115 Instance.getLibrary().setSourceCover("" + args[0], "" + args[1]);
5e848e6a
NR
116 } else if ("EXIT".equals(command)) {
117 stop(0, false);
b0e88ebd
NR
118 }
119
120 return null;
121 }
74a40dfb
NR
122
123 public static void sendStory(Story story, Object sender)
124 throws NoSuchFieldException, NoSuchMethodException,
125 ClassNotFoundException, IOException {
126
127 if (!story.getMeta().isImageDocument()) {
128 sendNextObject(sender, story);
129 return;
130 }
131
132 story = story.clone();
133
134 List<Chapter> chaps = story.getChapters();
135 story.setChapters(new ArrayList<Chapter>());
136 sendNextObject(sender, story);
137
138 for (Chapter chap : chaps) {
139 List<Paragraph> paras = chap.getParagraphs();
140 chap.setParagraphs(new ArrayList<Paragraph>());
141 sendNextObject(sender, chap);
142
143 for (Paragraph para : paras) {
144 sendNextObject(sender, para);
145 }
146 }
147 }
148
149 public static Story recStory(Object source) throws NoSuchFieldException,
150 NoSuchMethodException, ClassNotFoundException, IOException {
151
152 Story story = null;
153
154 Object obj = getNextObject(source);
155 if (obj instanceof Story) {
156 story = (Story) obj;
157
158 Chapter current = null;
159 for (obj = getNextObject(source); obj != null; obj = getNextObject(source)) {
160 if (obj instanceof Chapter) {
161 current = (Chapter) obj;
162 story.getChapters().add(current);
163 } else if (obj instanceof Paragraph) {
164 current.getParagraphs().add((Paragraph) obj);
165 }
166 }
167 }
168
169 return story;
170 }
171
172 private static Object getNextObject(Object clientOrServer)
173 throws NoSuchFieldException, NoSuchMethodException,
174 ClassNotFoundException, IOException {
175 if (clientOrServer instanceof ConnectActionClientObject) {
176 ConnectActionClientObject client = (ConnectActionClientObject) clientOrServer;
177 return client.send(null);
178 } else if (clientOrServer instanceof ConnectActionServerObject) {
179 ConnectActionServerObject server = (ConnectActionServerObject) clientOrServer;
180 Object obj = server.rec();
181 server.send(null);
182 return obj;
183 } else {
184 throw new ClassNotFoundException();
185 }
186 }
187
188 private static void sendNextObject(Object clientOrServer, Object obj)
189 throws NoSuchFieldException, NoSuchMethodException,
190 ClassNotFoundException, IOException {
191 if (clientOrServer instanceof ConnectActionClientObject) {
192 ConnectActionClientObject client = (ConnectActionClientObject) clientOrServer;
193 client.send(obj);
194 } else if (clientOrServer instanceof ConnectActionServerObject) {
195 ConnectActionServerObject server = (ConnectActionServerObject) clientOrServer;
196 server.send(obj);
197 server.rec();
198 } else {
199 throw new ClassNotFoundException();
200 }
201 }
b0e88ebd 202}