+ }
+
+ /* parse posts. */
+ SimpleXML postsXml = soneXml.getNode("posts");
+ Set<Post> posts = new HashSet<Post>();
+ if (postsXml == null) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded Sone %s has no posts!", new Object[] { sone });
+ } else {
+ for (SimpleXML postXml : postsXml.getNodes("post")) {
+ String postId = postXml.getValue("id", null);
+ String postRecipientId = postXml.getValue("recipient", null);
+ String postTime = postXml.getValue("time", null);
+ String postText = postXml.getValue("text", null);
+ if ((postId == null) || (postTime == null) || (postText == null)) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded post for Sone %s with missing data! ID: %s, Time: %s, Text: %s", new Object[] { sone, postId, postTime, postText });
+ return null;
+ }
+ try {
+ Post post = core.getPost(postId).setSone(sone).setTime(Long.parseLong(postTime)).setText(postText);
+ if ((postRecipientId != null) && (postRecipientId.length() == 43)) {
+ post.setRecipient(core.getSone(postRecipientId));
+ }
+ posts.add(post);
+ } catch (NumberFormatException nfe1) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded post for Sone %s with invalid time: %s", new Object[] { sone, postTime });
+ return null;
+ }
+ }
+ }
+
+ /* parse replies. */
+ SimpleXML repliesXml = soneXml.getNode("replies");
+ Set<PostReply> replies = new HashSet<PostReply>();
+ if (repliesXml == null) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded Sone %s has no replies!", new Object[] { sone });
+ } else {
+ for (SimpleXML replyXml : repliesXml.getNodes("reply")) {
+ String replyId = replyXml.getValue("id", null);
+ String replyPostId = replyXml.getValue("post-id", null);
+ String replyTime = replyXml.getValue("time", null);
+ String replyText = replyXml.getValue("text", null);
+ if ((replyId == null) || (replyPostId == null) || (replyTime == null) || (replyText == null)) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded reply for Sone %s with missing data! ID: %s, Post: %s, Time: %s, Text: %s", new Object[] { sone, replyId, replyPostId, replyTime, replyText });
+ return null;
+ }
+ try {
+ replies.add(core.getReply(replyId).setSone(sone).setPost(core.getPost(replyPostId)).setTime(Long.parseLong(replyTime)).setText(replyText));
+ } catch (NumberFormatException nfe1) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded reply for Sone %s with invalid time: %s", new Object[] { sone, replyTime });
+ return null;
+ }
+ }
+ }
+
+ /* parse liked post IDs. */
+ SimpleXML likePostIdsXml = soneXml.getNode("post-likes");
+ Set<String> likedPostIds = new HashSet<String>();
+ if (likePostIdsXml == null) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded Sone %s has no post likes!", new Object[] { sone });
+ } else {
+ for (SimpleXML likedPostIdXml : likePostIdsXml.getNodes("post-like")) {
+ String postId = likedPostIdXml.getValue();
+ likedPostIds.add(postId);
+ }
+ }
+
+ /* parse liked reply IDs. */
+ SimpleXML likeReplyIdsXml = soneXml.getNode("reply-likes");
+ Set<String> likedReplyIds = new HashSet<String>();
+ if (likeReplyIdsXml == null) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded Sone %s has no reply likes!", new Object[] { sone });
+ } else {
+ for (SimpleXML likedReplyIdXml : likeReplyIdsXml.getNodes("reply-like")) {
+ String replyId = likedReplyIdXml.getValue();
+ likedReplyIds.add(replyId);
+ }
+ }
+
+ /* parse albums. */
+ SimpleXML albumsXml = soneXml.getNode("albums");
+ List<Album> topLevelAlbums = new ArrayList<Album>();
+ if (albumsXml != null) {
+ for (SimpleXML albumXml : albumsXml.getNodes("album")) {
+ String id = albumXml.getValue("id", null);
+ String parentId = albumXml.getValue("parent", null);
+ String title = albumXml.getValue("title", null);
+ String description = albumXml.getValue("description", "");
+ String albumImageId = albumXml.getValue("album-image", null);
+ if ((id == null) || (title == null) || (description == null)) {
+ logger.log(Level.WARNING, "Downloaded Sone %s contains invalid album!", new Object[] { sone });
+ return null;
+ }
+ Album parent = null;
+ if (parentId != null) {
+ parent = core.getAlbum(parentId, false);
+ if (parent == null) {
+ logger.log(Level.WARNING, "Downloaded Sone %s has album with invalid parent!", new Object[] { sone });
+ return null;
+ }
+ }
+ Album album = core.getAlbum(id).setSone(sone).setTitle(title).setDescription(description);
+ if (parent != null) {
+ parent.addAlbum(album);
+ } else {
+ topLevelAlbums.add(album);
+ }
+ SimpleXML imagesXml = albumXml.getNode("images");
+ if (imagesXml != null) {
+ for (SimpleXML imageXml : imagesXml.getNodes("image")) {
+ String imageId = imageXml.getValue("id", null);
+ String imageCreationTimeString = imageXml.getValue("creation-time", null);
+ String imageKey = imageXml.getValue("key", null);
+ String imageTitle = imageXml.getValue("title", null);
+ String imageDescription = imageXml.getValue("description", "");
+ String imageWidthString = imageXml.getValue("width", null);
+ String imageHeightString = imageXml.getValue("height", null);
+ if ((imageId == null) || (imageCreationTimeString == null) || (imageKey == null) || (imageTitle == null) || (imageWidthString == null) || (imageHeightString == null)) {
+ logger.log(Level.WARNING, "Downloaded Sone %s contains invalid images!", new Object[] { sone });
+ return null;
+ }
+ long creationTime = Numbers.safeParseLong(imageCreationTimeString, 0L);
+ int imageWidth = Numbers.safeParseInteger(imageWidthString, 0);
+ int imageHeight = Numbers.safeParseInteger(imageHeightString, 0);
+ if ((imageWidth < 1) || (imageHeight < 1)) {
+ logger.log(Level.WARNING, "Downloaded Sone %s contains image %s with invalid dimensions (%s, %s)!", new Object[] { sone, imageId, imageWidthString, imageHeightString });
+ return null;
+ }
+ Image image = core.getImage(imageId).setSone(sone).setKey(imageKey).setCreationTime(creationTime);
+ image.setTitle(imageTitle).setDescription(imageDescription);
+ image.setWidth(imageWidth).setHeight(imageHeight);
+ album.addImage(image);
+ }
+ }
+ album.setAlbumImage(albumImageId);
+ }
+ }
+
+ /* process avatar. */
+ if (avatarId != null) {
+ profile.setAvatar(core.getImage(avatarId, false));
+ }
+
+ /* okay, apparently everything was parsed correctly. Now import. */
+ /* atomic setter operation on the Sone. */
+ synchronized (sone) {
+ sone.setProfile(profile);
+ sone.setPosts(posts);
+ sone.setReplies(replies);
+ sone.setLikePostIds(likedPostIds);
+ sone.setLikeReplyIds(likedReplyIds);
+ sone.setAlbums(topLevelAlbums);
+ }
+
+ return sone;
+ }
+
+ //
+ // SERVICE METHODS
+ //
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void serviceStop() {
+ for (Sone sone : sones) {
+ freenetInterface.unregisterUsk(sone);