+ @Override
+ public Optional<LocalSone> getLocalSone(String localSoneId) {
+ lock.readLock().lock();
+ try {
+ if (!localSones.contains(localSoneId)) {
+ return Optional.absent();
+ }
+ return Optional.of((LocalSone) allSones.get(localSoneId));
+ } finally {
+ lock.readLock().unlock();
+ }
+ }
+
+ @Override
+ public LocalSone registerLocalSone(OwnIdentity ownIdentity) {
+ final LocalSone localSone = loadLocalSone(ownIdentity);
+ localSones.add(ownIdentity.getId());
+ return localSone;
+ }
+
+ private LocalSone loadLocalSone(OwnIdentity ownIdentity) {
+ final SoneBuilder soneBuilder = newSoneBuilder().from(ownIdentity).using(
+ new Client("Sone", SonePlugin.VERSION.toString()));
+
+ loadElements(soneBuilder, ownIdentity.getId());
+
+ LocalSone localSone = soneBuilder.buildLocal();
+ loadSone(localSone);
+ localSone.setKnown(true);
+ localSone.setLatestEdition(
+ Optional.fromNullable(
+ Longs.tryParse(ownIdentity.getProperty(LATEST_EDITION_PROPERTY)))
+ .or(0L));
+ return localSone;
+ }
+
+ private void loadElements(SoneBuilder soneBuilder, String soneId) {
+ long soneTime = configurationLoader.getLocalSoneTime(soneId);
+ if (soneTime == -1) {
+ return;
+ }
+ soneBuilder.lastUpdated(soneTime);
+
+ ConfigurationSoneParser configurationSoneParser = new ConfigurationSoneParser(configuration, soneId);
+
+ try {
+ Set<Post> posts = configurationSoneParser.parsePosts(this);
+ soneBuilder.withPosts(posts);
+ for (Post post : posts) {
+ post.setKnown(true);
+ }
+ } catch (InvalidPostFound ipf) {
+ logger.log(Level.WARNING, "Invalid post found, aborting load!");
+ return;
+ }
+
+ try {
+ Set<PostReply> postReplies = configurationSoneParser.parsePostReplies(this);
+ soneBuilder.withPostReplies(postReplies);
+ for (PostReply reply : postReplies) {
+ reply.setKnown(true);
+ }
+ } catch (InvalidPostReplyFound iprf) {
+ logger.log(Level.WARNING, "Invalid reply found, aborting load!");
+ return;
+ }
+ }
+
+ private void loadSone(LocalSone sone) {
+ /* load profile. */
+ ConfigurationSoneParser configurationSoneParser = new ConfigurationSoneParser(configuration, sone.getId());
+ Profile profile = configurationSoneParser.parseProfile(sone);
+
+ /* load post likes. */
+ Set<String> likedPostIds = configurationSoneParser.parseLikedPostIds();
+
+ /* load reply likes. */
+ Set<String> likedReplyIds = configurationSoneParser.parseLikedPostReplyIds();
+
+ /* load albums. */
+ List<Album> topLevelAlbums;
+ try {
+ topLevelAlbums = configurationSoneParser.parseTopLevelAlbums(this, sone);
+ } catch (InvalidAlbumFound iaf) {
+ logger.log(Level.WARNING, "Invalid album found, aborting load!");
+ return;
+ } catch (InvalidParentAlbumFound ipaf) {
+ logger.log(Level.WARNING,
+ format("Invalid parent album ID: %s", ipaf.getAlbumParentId()));
+ return;
+ }
+
+ /* load images. */
+ try {
+ configurationSoneParser.parseImages(this, sone);
+ } catch (InvalidImageFound iif) {
+ logger.log(WARNING, "Invalid image found, aborting load!");
+ return;
+ } catch (InvalidParentAlbumFound ipaf) {
+ logger.log(Level.WARNING,
+ format("Invalid album image (%s) encountered, aborting load!",
+ ipaf.getAlbumParentId()));
+ return;
+ }
+
+ /* load avatar. */
+ String sonePrefix = "Sone/" + sone.getId();
+ String avatarId = configuration.getStringValue(sonePrefix + "/Profile/Avatar").getValue(null);
+ if (avatarId != null) {
+ final Map<String, Image> images = configurationSoneParser.getImages();
+ profile.setAvatar(images.get(avatarId));
+ }
+
+ /* load options. */
+ sone.getOptions().setAutoFollow(configuration.getBooleanValue(sonePrefix + "/Options/AutoFollow").getValue(null));
+ sone.getOptions().setSoneInsertNotificationEnabled(configuration.getBooleanValue(sonePrefix + "/Options/EnableSoneInsertNotifications").getValue(null));
+ sone.getOptions().setShowNewSoneNotifications(configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewSones").getValue(null));
+ sone.getOptions().setShowNewPostNotifications(configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewPosts").getValue(null));
+ sone.getOptions().setShowNewReplyNotifications(configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewReplies").getValue(null));
+ sone.getOptions().setShowCustomAvatars(ShowCustomAvatars.valueOf(
+ configuration.getStringValue(sonePrefix + "/Options/ShowCustomAvatars")
+ .getValue(ShowCustomAvatars.NEVER.name())));
+
+ /* if we’re still here, Sone was loaded successfully. */
+ lock.writeLock().lock();
+ try {
+ updateSoneTime(sone, sone.getTime());
+ sone.setProfile(profile);
+ sone.setLikePostIds(likedPostIds);
+ sone.setLikeReplyIds(likedReplyIds);
+
+ String lastInsertFingerprint = configurationLoader.getLastInsertFingerprint(sone.getId());
+ lastInsertFingerprints.put(sone.getId(), lastInsertFingerprint);
+
+ allSones.put(sone.getId(), sone);
+ storePosts(sone.getId(), sone.getPosts());
+ storePostReplies(sone.getId(), sone.getReplies());
+ storeAlbums(sone.getId(), topLevelAlbums);
+ storeImages(sone.getId(), from(topLevelAlbums).transformAndConcat(Album.FLATTENER).transformAndConcat(Album.IMAGES).toList());
+ } finally {
+ lock.writeLock().unlock();
+ }
+
+ logger.info(String.format("Sone loaded successfully: %s", sone));
+ }
+
+ @Override
+ public String getLastInsertFingerprint(Sone sone) {
+ lock.readLock().lock();
+ try {
+ if (!lastInsertFingerprints.containsKey(sone.getId())) {
+ return "";
+ }
+ return lastInsertFingerprints.get(sone.getId());
+ } finally {
+ lock.readLock().unlock();
+ }
+ }
+
+ @Override
+ public void setLastInsertFingerprint(Sone sone, String lastInsertFingerprint) {
+ lock.writeLock().lock();
+ try {
+ lastInsertFingerprints.put(sone.getId(), lastInsertFingerprint);
+ } finally {
+ lock.writeLock().unlock();
+ }
+ }
+