X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fcore%2FSoneParser.java;h=e1fd9ffcfd1f0dff7520062f4d5b86b5933d3661;hp=a9e2b3acbbc3aa06013b38d8ee756fbc8cef4988;hb=faf66247a34f64946990a985d2ea3003465969cb;hpb=2493e844ddeece59211c6a3c40e7ecc5d2cdb8b5 diff --git a/src/main/java/net/pterodactylus/sone/core/SoneParser.java b/src/main/java/net/pterodactylus/sone/core/SoneParser.java index a9e2b3a..e1fd9ff 100644 --- a/src/main/java/net/pterodactylus/sone/core/SoneParser.java +++ b/src/main/java/net/pterodactylus/sone/core/SoneParser.java @@ -1,58 +1,46 @@ package net.pterodactylus.sone.core; -import static java.util.logging.Logger.getLogger; -import static net.pterodactylus.sone.utils.NumberParsers.parseInt; -import static net.pterodactylus.sone.utils.NumberParsers.parseLong; +import static java.util.concurrent.TimeUnit.*; +import static java.util.logging.Logger.*; +import static net.pterodactylus.sone.utils.NumberParsers.*; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; +import java.io.*; +import java.util.*; +import java.util.logging.*; -import javax.inject.Inject; +import javax.annotation.*; +import javax.inject.*; -import net.pterodactylus.sone.data.Album; -import net.pterodactylus.sone.data.Client; -import net.pterodactylus.sone.data.Image; -import net.pterodactylus.sone.data.Post; -import net.pterodactylus.sone.data.PostReply; -import net.pterodactylus.sone.data.Profile; -import net.pterodactylus.sone.data.Profile.DuplicateField; -import net.pterodactylus.sone.data.Profile.EmptyFieldName; -import net.pterodactylus.sone.data.Sone; -import net.pterodactylus.sone.database.Database; -import net.pterodactylus.sone.database.PostBuilder; -import net.pterodactylus.sone.database.PostReplyBuilder; -import net.pterodactylus.sone.database.SoneBuilder; -import net.pterodactylus.util.xml.SimpleXML; -import net.pterodactylus.util.xml.XML; +import net.pterodactylus.sone.data.*; +import net.pterodactylus.sone.data.Profile.*; +import net.pterodactylus.sone.database.*; +import net.pterodactylus.util.xml.*; -import org.w3c.dom.Document; +import com.codahale.metrics.*; +import com.google.common.base.*; +import org.w3c.dom.*; /** * Parses a {@link Sone} from an XML {@link InputStream}. - * - * @author David ‘Bombe’ Roden */ public class SoneParser { private static final Logger logger = getLogger(SoneParser.class.getName()); private static final int MAX_PROTOCOL_VERSION = 0; private final Database database; + private final Histogram soneParsingDurationHistogram; @Inject - public SoneParser(Database database) { + public SoneParser(Database database, MetricRegistry metricRegistry) { this.database = database; + this.soneParsingDurationHistogram = metricRegistry.histogram("sone.parse.duration", () -> new Histogram(new ExponentiallyDecayingReservoir(3000, 0))); } + @Nullable public Sone parseSone(Sone originalSone, InputStream soneInputStream) throws SoneException { /* TODO - impose a size limit? */ + Stopwatch stopwatch = Stopwatch.createStarted(); Document document; /* XML parsing is not thread-safe. */ synchronized (this) { @@ -168,7 +156,7 @@ public class SoneParser { /* parse posts. */ SimpleXML postsXml = soneXml.getNode("posts"); - Set posts = new HashSet(); + Set posts = new HashSet<>(); if (postsXml == null) { /* TODO - mark Sone as bad. */ logger.log(Level.WARNING, String.format("Downloaded Sone %s has no posts!", sone)); @@ -201,7 +189,7 @@ public class SoneParser { /* parse replies. */ SimpleXML repliesXml = soneXml.getNode("replies"); - Set replies = new HashSet(); + Set replies = new HashSet<>(); if (repliesXml == null) { /* TODO - mark Sone as bad. */ logger.log(Level.WARNING, String.format("Downloaded Sone %s has no replies!", sone)); @@ -231,7 +219,7 @@ public class SoneParser { /* parse liked post IDs. */ SimpleXML likePostIdsXml = soneXml.getNode("post-likes"); - Set likedPostIds = new HashSet(); + Set likedPostIds = new HashSet<>(); if (likePostIdsXml == null) { /* TODO - mark Sone as bad. */ logger.log(Level.WARNING, String.format("Downloaded Sone %s has no post likes!", sone)); @@ -244,7 +232,7 @@ public class SoneParser { /* parse liked reply IDs. */ SimpleXML likeReplyIdsXml = soneXml.getNode("reply-likes"); - Set likedReplyIds = new HashSet(); + Set likedReplyIds = new HashSet<>(); if (likeReplyIdsXml == null) { /* TODO - mark Sone as bad. */ logger.log(Level.WARNING, String.format("Downloaded Sone %s has no reply likes!", sone)); @@ -257,8 +245,9 @@ public class SoneParser { /* parse albums. */ SimpleXML albumsXml = soneXml.getNode("albums"); - Map allImages = new HashMap(); - List topLevelAlbums = new ArrayList(); + Map allImages = new HashMap<>(); + List topLevelAlbums = new ArrayList<>(); + Map allAlbums = new HashMap<>(); if (albumsXml != null) { for (SimpleXML albumXml : albumsXml.getNodes("album")) { String id = albumXml.getValue("id", null); @@ -271,7 +260,7 @@ public class SoneParser { } Album parent = null; if (parentId != null) { - parent = database.getAlbum(parentId); + parent = allAlbums.get(parentId); if (parent == null) { logger.log(Level.WARNING, String.format("Downloaded Sone %s has album with invalid parent!", sone)); return null; @@ -290,6 +279,7 @@ public class SoneParser { } else { topLevelAlbums.add(album); } + allAlbums.put(album.getId(), album); SimpleXML imagesXml = albumXml.getNode("images"); if (imagesXml != null) { for (SimpleXML imageXml : imagesXml.getNodes("image")) { @@ -336,6 +326,11 @@ public class SoneParser { sone.getRootAlbum().addAlbum(album); } + // record the duration + stopwatch.stop(); + soneParsingDurationHistogram.update(stopwatch.elapsed(MICROSECONDS)); + logger.fine(() -> "Parsed " + originalSone.getIdentity().getId() + "@" + originalSone.getLatestEdition() + " in " + stopwatch.elapsed(MICROSECONDS) + "μs."); + return sone; }