Add processor for updated Sones
[Sone.git] / src / main / java / net / pterodactylus / sone / core / ConfigurationSoneParser.java
1 package net.pterodactylus.sone.core;
2
3 import static java.util.Collections.unmodifiableMap;
4
5 import java.util.ArrayList;
6 import java.util.HashMap;
7 import java.util.HashSet;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Set;
11
12 import javax.annotation.Nullable;
13
14 import net.pterodactylus.sone.data.Album;
15 import net.pterodactylus.sone.data.Image;
16 import net.pterodactylus.sone.data.Post;
17 import net.pterodactylus.sone.data.PostReply;
18 import net.pterodactylus.sone.data.Profile;
19 import net.pterodactylus.sone.data.Sone;
20 import net.pterodactylus.sone.database.AlbumBuilderFactory;
21 import net.pterodactylus.sone.database.ImageBuilderFactory;
22 import net.pterodactylus.sone.database.PostBuilder;
23 import net.pterodactylus.sone.database.PostBuilderFactory;
24 import net.pterodactylus.sone.database.PostReplyBuilder;
25 import net.pterodactylus.sone.database.PostReplyBuilderFactory;
26 import net.pterodactylus.util.config.Configuration;
27
28 /**
29  * Parses a {@link Sone}’s data from a {@link Configuration}.
30  */
31 public class ConfigurationSoneParser {
32
33         private final Configuration configuration;
34         private final Sone sone;
35         private final String sonePrefix;
36         private final Map<String, Album> albums = new HashMap<String, Album>();
37         private final List<Album> topLevelAlbums = new ArrayList<Album>();
38         private final Map<String, Image> images = new HashMap<String, Image>();
39
40         public ConfigurationSoneParser(Configuration configuration, Sone sone) {
41                 this.configuration = configuration;
42                 this.sone = sone;
43                 sonePrefix = "Sone/" + sone.getId();
44         }
45
46         public Profile parseProfile() {
47                 Profile profile = new Profile(sone);
48                 profile.setFirstName(getString("/Profile/FirstName", null));
49                 profile.setMiddleName(getString("/Profile/MiddleName", null));
50                 profile.setLastName(getString("/Profile/LastName", null));
51                 profile.setBirthDay(getInt("/Profile/BirthDay", null));
52                 profile.setBirthMonth(getInt("/Profile/BirthMonth", null));
53                 profile.setBirthYear(getInt("/Profile/BirthYear", null));
54
55                 /* load profile fields. */
56                 int fieldCount = 0;
57                 while (true) {
58                         String fieldPrefix = "/Profile/Fields/" + fieldCount++;
59                         String fieldName = getString(fieldPrefix + "/Name", null);
60                         if (fieldName == null) {
61                                 break;
62                         }
63                         String fieldValue = getString(fieldPrefix + "/Value", "");
64                         profile.addField(fieldName).setValue(fieldValue);
65                 }
66
67                 return profile;
68         }
69
70         private String getString(String nodeName, @Nullable String defaultValue) {
71                 return configuration.getStringValue(sonePrefix + nodeName)
72                                 .getValue(defaultValue);
73         }
74
75         private Integer getInt(String nodeName, @Nullable Integer defaultValue) {
76                 return configuration.getIntValue(sonePrefix + nodeName)
77                                 .getValue(defaultValue);
78         }
79
80         private Long getLong(String nodeName, @Nullable Long defaultValue) {
81                 return configuration.getLongValue(sonePrefix + nodeName)
82                                 .getValue(defaultValue);
83         }
84
85         public Set<Post> parsePosts(PostBuilderFactory postBuilderFactory)
86         throws InvalidPostFound {
87                 Set<Post> posts = new HashSet<Post>();
88                 while (true) {
89                         String postPrefix = "/Posts/" + posts.size();
90                         String postId = getString(postPrefix + "/ID", null);
91                         if (postId == null) {
92                                 break;
93                         }
94                         long postTime = getLong(postPrefix + "/Time", 0L);
95                         String postText = getString(postPrefix + "/Text", null);
96                         if (postAttributesAreInvalid(postTime, postText)) {
97                                 throw new InvalidPostFound();
98                         }
99                         PostBuilder postBuilder = postBuilderFactory.newPostBuilder()
100                                         .withId(postId)
101                                         .from(sone.getId())
102                                         .withTime(postTime)
103                                         .withText(postText);
104                         String postRecipientId =
105                                         getString(postPrefix + "/Recipient", null);
106                         if (postRecipientIsValid(postRecipientId)) {
107                                 postBuilder.to(postRecipientId);
108                         }
109                         posts.add(postBuilder.build());
110                 }
111                 return posts;
112         }
113
114         private boolean postAttributesAreInvalid(long postTime, String postText) {
115                 return (postTime == 0) || (postText == null);
116         }
117
118         private boolean postRecipientIsValid(String postRecipientId) {
119                 return (postRecipientId != null) && (postRecipientId.length() == 43);
120         }
121
122         public Set<PostReply> parsePostReplies(
123                         PostReplyBuilderFactory postReplyBuilderFactory) {
124                 Set<PostReply> replies = new HashSet<PostReply>();
125                 while (true) {
126                         String replyPrefix = "/Replies/" + replies.size();
127                         String replyId = getString(replyPrefix + "/ID", null);
128                         if (replyId == null) {
129                                 break;
130                         }
131                         String postId = getString(replyPrefix + "/Post/ID", null);
132                         long replyTime = getLong(replyPrefix + "/Time", 0L);
133                         String replyText = getString(replyPrefix + "/Text", null);
134                         if ((postId == null) || (replyTime == 0) || (replyText == null)) {
135                                 throw new InvalidPostReplyFound();
136                         }
137                         PostReplyBuilder postReplyBuilder = postReplyBuilderFactory
138                                         .newPostReplyBuilder()
139                                         .withId(replyId)
140                                         .from(sone.getId())
141                                         .to(postId)
142                                         .withTime(replyTime)
143                                         .withText(replyText);
144                         replies.add(postReplyBuilder.build());
145                 }
146                 return replies;
147         }
148
149         public Set<String> parseLikedPostIds() {
150                 Set<String> likedPostIds = new HashSet<String>();
151                 while (true) {
152                         String likedPostId =
153                                         getString("/Likes/Post/" + likedPostIds.size() + "/ID",
154                                                         null);
155                         if (likedPostId == null) {
156                                 break;
157                         }
158                         likedPostIds.add(likedPostId);
159                 }
160                 return likedPostIds;
161         }
162
163         public Set<String> parseLikedPostReplyIds() {
164                 Set<String> likedPostReplyIds = new HashSet<String>();
165                 while (true) {
166                         String likedReplyId = getString(
167                                         "/Likes/Reply/" + likedPostReplyIds.size() + "/ID", null);
168                         if (likedReplyId == null) {
169                                 break;
170                         }
171                         likedPostReplyIds.add(likedReplyId);
172                 }
173                 return likedPostReplyIds;
174         }
175
176         public Set<String> parseFriends() {
177                 Set<String> friends = new HashSet<String>();
178                 while (true) {
179                         String friendId =
180                                         getString("/Friends/" + friends.size() + "/ID", null);
181                         if (friendId == null) {
182                                 break;
183                         }
184                         friends.add(friendId);
185                 }
186                 return friends;
187         }
188
189         public List<Album> parseTopLevelAlbums(
190                         AlbumBuilderFactory albumBuilderFactory) {
191                 int albumCounter = 0;
192                 while (true) {
193                         String albumPrefix = "/Albums/" + albumCounter++;
194                         String albumId = getString(albumPrefix + "/ID", null);
195                         if (albumId == null) {
196                                 break;
197                         }
198                         String albumTitle = getString(albumPrefix + "/Title", null);
199                         String albumDescription =
200                                         getString(albumPrefix + "/Description", null);
201                         String albumParentId = getString(albumPrefix + "/Parent", null);
202                         if ((albumTitle == null) || (albumDescription == null)) {
203                                 throw new InvalidAlbumFound();
204                         }
205                         Album album = albumBuilderFactory.newAlbumBuilder()
206                                         .withId(albumId)
207                                         .by(sone)
208                                         .build()
209                                         .modify()
210                                         .setTitle(albumTitle)
211                                         .setDescription(albumDescription)
212                                         .update();
213                         if (albumParentId != null) {
214                                 Album parentAlbum = albums.get(albumParentId);
215                                 if (parentAlbum == null) {
216                                         throw new InvalidParentAlbumFound(albumParentId);
217                                 }
218                                 parentAlbum.addAlbum(album);
219                         } else {
220                                 topLevelAlbums.add(album);
221                         }
222                         albums.put(albumId, album);
223                 }
224                 return topLevelAlbums;
225         }
226
227         public Map<String, Album> getAlbums() {
228                 return unmodifiableMap(albums);
229         }
230
231         public void parseImages(ImageBuilderFactory imageBuilderFactory) {
232                 int imageCounter = 0;
233                 while (true) {
234                         String imagePrefix = "/Images/" + imageCounter++;
235                         String imageId = getString(imagePrefix + "/ID", null);
236                         if (imageId == null) {
237                                 break;
238                         }
239                         String albumId = getString(imagePrefix + "/Album", null);
240                         String key = getString(imagePrefix + "/Key", null);
241                         String title = getString(imagePrefix + "/Title", null);
242                         String description =
243                                         getString(imagePrefix + "/Description", null);
244                         Long creationTime = getLong(imagePrefix + "/CreationTime", null);
245                         Integer width = getInt(imagePrefix + "/Width", null);
246                         Integer height = getInt(imagePrefix + "/Height", null);
247                         if (albumAttributesAreInvalid(albumId, key, title, description,
248                                         creationTime,
249                                         width, height)) {
250                                 throw new InvalidImageFound();
251                         }
252                         Album album = albums.get(albumId);
253                         if (album == null) {
254                                 throw new InvalidParentAlbumFound(albumId);
255                         }
256                         Image image = imageBuilderFactory.newImageBuilder()
257                                         .withId(imageId)
258                                         .build()
259                                         .modify()
260                                         .setSone(sone)
261                                         .setCreationTime(creationTime)
262                                         .setKey(key)
263                                         .setTitle(title)
264                                         .setDescription(description)
265                                         .setWidth(width)
266                                         .setHeight(height)
267                                         .update();
268                         album.addImage(image);
269                         images.put(image.getId(), image);
270                 }
271         }
272
273         public Map<String, Image> getImages() {
274                 return images;
275         }
276
277         private boolean albumAttributesAreInvalid(String albumId, String key,
278                         String title, String description, Long creationTime,
279                         Integer width, Integer height) {
280                 return (albumId == null) || (key == null) || (title == null) || (
281                                 description == null) || (creationTime == null) || (width
282                                 == null) || (height == null);
283         }
284
285         public static class InvalidPostFound extends RuntimeException { }
286
287         public static class InvalidPostReplyFound extends RuntimeException { }
288
289         public static class InvalidAlbumFound extends RuntimeException { }
290
291         public static class InvalidParentAlbumFound extends RuntimeException {
292
293                 private final String albumParentId;
294
295                 public InvalidParentAlbumFound(String albumParentId) {
296                         this.albumParentId = albumParentId;
297                 }
298
299                 public String getAlbumParentId() {
300                         return albumParentId;
301                 }
302
303         }
304
305         public static class InvalidImageFound extends RuntimeException { }
306
307 }