package net.pterodactylus.sone.core;
+import static java.util.concurrent.TimeUnit.*;
import static java.util.logging.Logger.getLogger;
import static net.pterodactylus.sone.utils.NumberParsers.parseInt;
import static net.pterodactylus.sone.utils.NumberParsers.parseLong;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.pterodactylus.util.xml.SimpleXML;
import net.pterodactylus.util.xml.XML;
+import com.codahale.metrics.*;
+import com.google.common.base.*;
import org.w3c.dom.Document;
/**
* Parses a {@link Sone} from an XML {@link InputStream}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
*/
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.parsing.duration");
}
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) {
/* parse posts. */
SimpleXML postsXml = soneXml.getNode("posts");
- Set<Post> posts = new HashSet<Post>();
+ Set<Post> posts = new HashSet<>();
if (postsXml == null) {
/* TODO - mark Sone as bad. */
logger.log(Level.WARNING, String.format("Downloaded Sone %s has no posts!", sone));
/* parse replies. */
SimpleXML repliesXml = soneXml.getNode("replies");
- Set<PostReply> replies = new HashSet<PostReply>();
+ Set<PostReply> replies = new HashSet<>();
if (repliesXml == null) {
/* TODO - mark Sone as bad. */
logger.log(Level.WARNING, String.format("Downloaded Sone %s has no replies!", sone));
/* parse liked post IDs. */
SimpleXML likePostIdsXml = soneXml.getNode("post-likes");
- Set<String> likedPostIds = new HashSet<String>();
+ Set<String> 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));
/* parse liked reply IDs. */
SimpleXML likeReplyIdsXml = soneXml.getNode("reply-likes");
- Set<String> likedReplyIds = new HashSet<String>();
+ Set<String> 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));
/* parse albums. */
SimpleXML albumsXml = soneXml.getNode("albums");
- Map<String, Image> allImages = new HashMap<String, Image>();
- List<Album> topLevelAlbums = new ArrayList<Album>();
+ Map<String, Image> allImages = new HashMap<>();
+ List<Album> topLevelAlbums = new ArrayList<>();
+ Map<String, Album> allAlbums = new HashMap<>();
if (albumsXml != null) {
for (SimpleXML albumXml : albumsXml.getNodes("album")) {
String id = albumXml.getValue("id", null);
}
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;
} else {
topLevelAlbums.add(album);
}
+ allAlbums.put(album.getId(), album);
SimpleXML imagesXml = albumXml.getNode("images");
if (imagesXml != null) {
for (SimpleXML imageXml : imagesXml.getNodes("image")) {
sone.getRootAlbum().addAlbum(album);
}
+ // record the duration
+ stopwatch.stop();
+ soneParsingDurationHistogram.update(stopwatch.elapsed(MICROSECONDS));
+
return sone;
}