import java.io.IOException;
import java.io.InputStream;
+import java.net.MalformedURLException;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
* The Freenet interface
*/
public SoneDownloader(Core core, FreenetInterface freenetInterface) {
- super("Sone Downloader");
+ super("Sone Downloader", false);
this.core = core;
this.freenetInterface = freenetInterface;
}
* The Sone to fetch
*/
public void fetchSone(Sone sone) {
+ if (core.getSoneStatus(sone) == SoneStatus.downloading) {
+ return;
+ }
logger.log(Level.FINE, "Starting fetch for Sone ā%sā from %sā¦", new Object[] { sone, sone.getRequestUri().setMetaString(new String[] { "sone.xml" }) });
FreenetURI requestUri = sone.getRequestUri().setMetaString(new String[] { "sone.xml" });
core.setSoneStatus(sone, SoneStatus.downloading);
try {
xmlBucket = fetchResult.asBucket();
xmlInputStream = xmlBucket.getInputStream();
- Document document = XML.transformToDocument(xmlInputStream);
+ Document document;
+ /* XML parsing is not thread-safe. */
+ synchronized (this) {
+ document = XML.transformToDocument(xmlInputStream);
+ }
+ if (document == null) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Could not parse XML for Sone %s at %s!", new Object[] { originalSone, requestUri });
+ return null;
+ }
SimpleXML soneXml;
try {
soneXml = SimpleXML.fromDocument(document);
}
}
+ /* parse liked post IDs. */
+ SimpleXML likePostIdsXml = soneXml.getNode("post-likes");
+ if (likePostIdsXml == null) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded Sone %s has no post likes!", new Object[] { sone });
+ return null;
+ }
+
+ Set<String> likedPostIds = new HashSet<String>();
+ for (SimpleXML likedPostIdXml : likePostIdsXml.getNodes("post-like")) {
+ String postId = likedPostIdXml.getValue();
+ likedPostIds.add(postId);
+ }
+
+ /* parse liked reply IDs. */
+ SimpleXML likeReplyIdsXml = soneXml.getNode("reply-likes");
+ if (likeReplyIdsXml == null) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded Sone %s has no reply likes!", new Object[] { sone });
+ return null;
+ }
+
+ Set<String> likedReplyIds = new HashSet<String>();
+ for (SimpleXML likedReplyIdXml : likeReplyIdsXml.getNodes("reply-like")) {
+ String replyId = likedReplyIdXml.getValue();
+ likedReplyIds.add(replyId);
+ }
+
+ /* parse known Sones. */
+ SimpleXML knownSonesXml = soneXml.getNode("known-sones");
+ if (knownSonesXml == null) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded Sone %s has no known Sones!", new Object[] { sone });
+ return null;
+ }
+
+ Set<Sone> knownSones = new HashSet<Sone>();
+ for (SimpleXML knownSoneXml : knownSonesXml.getNodes("known-sone")) {
+ String knownSoneId = knownSoneXml.getValue("sone-id", null);
+ String knownSoneKey = knownSoneXml.getValue("sone-key", null);
+ String knownSoneName = knownSoneXml.getValue("sone-name", null);
+ if ((knownSoneId == null) || (knownSoneKey == null) || (knownSoneName == null)) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded known Sone for Sone %s with missing data! ID: %s, Key: %s, Name: %s", new Object[] { sone, knownSoneId, knownSoneKey, knownSoneName });
+ return null;
+ }
+ try {
+ knownSones.add(core.getSone(knownSoneId).setRequestUri(new FreenetURI(knownSoneKey)).setName(knownSoneName));
+ } catch (MalformedURLException mue1) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded known Sone for Sone %s with invalid key: %s", new Object[] { sone, knownSoneKey });
+ return null;
+ }
+ }
+
/* 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.setModificationCounter(0);
}
+
+ /* add all known Sones to core for downloading. */
+ for (Sone knownSone : knownSones) {
+ core.addSone(knownSone);
+ }
+
} catch (IOException ioe1) {
logger.log(Level.WARNING, "Could not read XML file from " + originalSone + "!", ioe1);
return null;