import java.net.MalformedURLException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import net.pterodactylus.sone.data.Sone.ShowCustomAvatars;
import net.pterodactylus.sone.data.Sone.SoneStatus;
import net.pterodactylus.sone.data.TemporaryImage;
+ import net.pterodactylus.sone.data.impl.PostImpl;
+import net.pterodactylus.sone.database.Database;
import net.pterodactylus.sone.fcp.FcpInterface;
import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired;
import net.pterodactylus.sone.freenet.wot.Identity;
import net.pterodactylus.sone.freenet.wot.IdentityListener;
import net.pterodactylus.sone.freenet.wot.IdentityManager;
import net.pterodactylus.sone.freenet.wot.OwnIdentity;
- import net.pterodactylus.sone.freenet.wot.Trust;
- import net.pterodactylus.sone.freenet.wot.WebOfTrustException;
import net.pterodactylus.sone.main.SonePlugin;
import net.pterodactylus.util.config.Configuration;
import net.pterodactylus.util.config.ConfigurationException;
/** Whether we’re currently saving the configuration. */
private boolean storingConfiguration = false;
+ /** The database. */
+ private Database database;
+
/** The identity manager. */
private final IdentityManager identityManager;
/** The update checker. */
private final UpdateChecker updateChecker;
+ /** The trust updater. */
+ private final WebOfTrustUpdater webOfTrustUpdater;
+
/** The FCP interface. */
private volatile FcpInterface fcpInterface;
/* synchronize access on this on localSones. */
private final Map<Sone, SoneRescuer> soneRescuers = new HashMap<Sone, SoneRescuer>();
- /** All local Sones. */
- /* synchronize access on this on itself. */
- private final Map<String, Sone> localSones = new HashMap<String, Sone>();
-
- /** All remote Sones. */
- /* synchronize access on this on itself. */
- private final Map<String, Sone> remoteSones = new HashMap<String, Sone>();
-
/** All known Sones. */
private final Set<String> knownSones = new HashSet<String>();
*
* @param configuration
* The configuration of the core
+ * @param database
+ * The database to use
* @param freenetInterface
* The freenet interface
* @param identityManager
* The identity manager
+ * @param webOfTrustUpdater
+ * The WebOfTrust updater
*/
- public Core(Configuration configuration, Database database, FreenetInterface freenetInterface, IdentityManager identityManager) {
- public Core(Configuration configuration, FreenetInterface freenetInterface, IdentityManager identityManager, WebOfTrustUpdater webOfTrustUpdater) {
++ public Core(Configuration configuration, Database database, FreenetInterface freenetInterface, IdentityManager identityManager, WebOfTrustUpdater webOfTrustUpdater) {
super("Sone Core");
this.configuration = configuration;
+ this.database = database;
this.freenetInterface = freenetInterface;
this.identityManager = identityManager;
this.soneDownloader = new SoneDownloader(this, freenetInterface);
this.imageInserter = new ImageInserter(this, freenetInterface);
this.updateChecker = new UpdateChecker(freenetInterface);
+ this.webOfTrustUpdater = webOfTrustUpdater;
}
//
* @return The Sone rescuer for the given Sone
*/
public SoneRescuer getSoneRescuer(Sone sone) {
- Validation.begin().isNotNull("Sone", sone).check().is("Local Sone", isLocalSone(sone)).check();
- synchronized (localSones) {
+ Validation.begin().isNotNull("Sone", sone).check().is("Local Sone", sone.isLocal()).check();
+ synchronized (soneRescuers) {
SoneRescuer soneRescuer = soneRescuers.get(sone);
if (soneRescuer == null) {
soneRescuer = new SoneRescuer(this, soneDownloader, sone);
*
* @return All Sones
*/
- public Set<Sone> getSones() {
- Set<Sone> allSones = new HashSet<Sone>();
- allSones.addAll(getLocalSones());
- allSones.addAll(getRemoteSones());
- return allSones;
+ public Collection<Sone> getSones() {
+ return database.getSones();
}
/**
*/
@Override
public Sone getSone(String id, boolean create) {
- if (isLocalSone(id)) {
- return getLocalSone(id);
- }
- return getRemoteSone(id, create);
+ return database.getSone(id, create);
}
/**
* otherwise
*/
public boolean hasSone(String id) {
- return isLocalSone(id) || isRemoteSone(id);
- }
-
- /**
- * Returns whether the given Sone is a local Sone.
- *
- * @param sone
- * The Sone to check for its locality
- * @return {@code true} if the given Sone is local, {@code false} otherwise
- */
- public boolean isLocalSone(Sone sone) {
- synchronized (localSones) {
- return localSones.containsKey(sone.getId());
- }
- }
-
- /**
- * Returns whether the given ID is the ID of a local Sone.
- *
- * @param id
- * The Sone ID to check for its locality
- * @return {@code true} if the given ID is a local Sone, {@code false}
- * otherwise
- */
- public boolean isLocalSone(String id) {
- synchronized (localSones) {
- return localSones.containsKey(id);
- }
+ return database.getSone(id, false) != null;
}
/**
*
* @return All local Sones
*/
- public Set<Sone> getLocalSones() {
- synchronized (localSones) {
- return new HashSet<Sone>(localSones.values());
- }
+ public Collection<Sone> getLocalSones() {
+ return database.getLocalSones();
}
/**
* @return The Sone with the given ID, or {@code null}
*/
public Sone getLocalSone(String id, boolean create) {
- synchronized (localSones) {
- Sone sone = localSones.get(id);
- if ((sone == null) && create) {
- sone = new Sone(id);
- localSones.put(id, sone);
- }
- return sone;
- }
+ return database.getLocalSone(id, create);
}
/**
*
* @return All remote Sones
*/
- public Set<Sone> getRemoteSones() {
- synchronized (remoteSones) {
- return new HashSet<Sone>(remoteSones.values());
- }
+ public Collection<Sone> getRemoteSones() {
+ return database.getRemoteSones();
}
/**
* @return The Sone with the given ID
*/
public Sone getRemoteSone(String id, boolean create) {
- synchronized (remoteSones) {
- Sone sone = remoteSones.get(id);
- if ((sone == null) && create && (id != null) && (id.length() == 43)) {
- sone = new Sone(id);
- remoteSones.put(id, sone);
- }
- return sone;
- }
- }
-
- /**
- * Returns whether the given Sone is a remote Sone.
- *
- * @param sone
- * The Sone to check
- * @return {@code true} if the given Sone is a remote Sone, {@code false}
- * otherwise
- */
- public boolean isRemoteSone(Sone sone) {
- synchronized (remoteSones) {
- return remoteSones.containsKey(sone.getId());
- }
- }
-
- /**
- * Returns whether the Sone with the given ID is a remote Sone.
- *
- * @param id
- * The ID of the Sone to check
- * @return {@code true} if the Sone with the given ID is a remote Sone,
- * {@code false} otherwise
- */
- public boolean isRemoteSone(String id) {
- synchronized (remoteSones) {
- return remoteSones.containsKey(id);
- }
+ return database.getRemoteSone(id, create);
}
/**
}
/**
- * Returns the post with the given ID.
- *
- * @param postId
- * The ID of the post to get
- * @return The post with the given ID, or a new post with the given ID
- */
- public Post getPost(String postId) {
- return getPost(postId, true);
- }
-
- /**
* Returns the post with the given ID, optionally creating a new post.
*
* @param postId
synchronized (posts) {
Post post = posts.get(postId);
if ((post == null) && create) {
- post = new Post(postId);
+ post = new PostImpl(postId);
posts.put(postId, post);
}
return post;
* @return All replies for the given post
*/
public List<PostReply> getReplies(Post post) {
- Set<Sone> sones = getSones();
+ Collection<Sone> sones = getSones();
List<PostReply> replies = new ArrayList<PostReply>();
for (Sone sone : sones) {
for (PostReply reply : sone.getReplies()) {
}
/**
- <<<<<<< HEAD
- =======
- * Adds a local Sone from the given ID which has to be the ID of an own
- * identity.
- *
- * @param id
- * The ID of an own identity to add a Sone for
- * @return The added (or already existing) Sone
- */
- public Sone addLocalSone(String id) {
- if (database.getLocalSone(id, false) != null) {
- logger.log(Level.FINE, "Tried to add known local Sone: %s", id);
- return database.getLocalSone(id, false);
- }
- OwnIdentity ownIdentity = identityManager.getOwnIdentity(id);
- if (ownIdentity == null) {
- logger.log(Level.INFO, "Invalid Sone ID: %s", id);
- return null;
- }
- return addLocalSone(ownIdentity);
- }
-
- /**
- >>>>>>> 4f36598... Store locality of a Sone in the Sone itself, remove related methods from Database.
* Adds a local Sone from the given own identity.
*
* @param ownIdentity
logger.log(Level.WARNING, "Given OwnIdentity is null!");
return null;
}
- synchronized (localSones) {
- final Sone sone;
- try {
- sone = getLocalSone(ownIdentity.getId()).setIdentity(ownIdentity).setInsertUri(new FreenetURI(ownIdentity.getInsertUri())).setRequestUri(new FreenetURI(ownIdentity.getRequestUri()));
- } catch (MalformedURLException mue1) {
- logger.log(Level.SEVERE, String.format("Could not convert the Identity’s URIs to Freenet URIs: %s, %s", ownIdentity.getInsertUri(), ownIdentity.getRequestUri()), mue1);
- return null;
- }
- sone.setLatestEdition(Numbers.safeParseLong(ownIdentity.getProperty("Sone.LatestEdition"), (long) 0));
- sone.setClient(new Client("Sone", SonePlugin.VERSION.toString()));
- sone.setKnown(true);
- /* TODO - load posts ’n stuff */
- localSones.put(ownIdentity.getId(), sone);
- final SoneInserter soneInserter = new SoneInserter(this, freenetInterface, sone);
- soneInserter.addSoneInsertListener(this);
- soneInserters.put(sone, soneInserter);
- sone.setStatus(SoneStatus.idle);
- loadSone(sone);
- soneInserter.start();
- return sone;
+ Sone sone;
+ try {
+ sone = getLocalSone(ownIdentity.getId()).setIdentity(ownIdentity).setInsertUri(new FreenetURI(ownIdentity.getInsertUri())).setRequestUri(new FreenetURI(ownIdentity.getRequestUri()));
+ } catch (MalformedURLException mue1) {
+ logger.log(Level.SEVERE, String.format("Could not convert the Identity’s URIs to Freenet URIs: %s, %s", ownIdentity.getInsertUri(), ownIdentity.getRequestUri()), mue1);
+ return null;
}
+ sone.setLatestEdition(Numbers.safeParseLong(ownIdentity.getProperty("Sone.LatestEdition"), (long) 0));
+ sone.setClient(new Client("Sone", SonePlugin.VERSION.toString()));
+ sone.setKnown(true);
+ /* TODO - load posts ’n stuff */
+ final SoneInserter soneInserter = new SoneInserter(this, freenetInterface, sone);
+ soneInserter.addSoneInsertListener(this);
+ soneInserters.put(sone, soneInserter);
+ sone.setStatus(SoneStatus.idle);
+ loadSone(sone);
+ soneInserter.start();
+ database.saveSone(sone);
+ return sone;
}
/**
* @return The created Sone
*/
public Sone createSone(OwnIdentity ownIdentity) {
- try {
- ownIdentity.addContext("Sone");
- } catch (WebOfTrustException wote1) {
- logger.log(Level.SEVERE, String.format("Could not add “Sone” context to own identity: %s", ownIdentity), wote1);
+ if (!webOfTrustUpdater.addContextWait(ownIdentity, "Sone")) {
+ logger.log(Level.SEVERE, String.format("Could not add “Sone” context to own identity: %s", ownIdentity));
return null;
}
Sone sone = addLocalSone(ownIdentity);
logger.log(Level.WARNING, "Given Identity is null!");
return null;
}
- synchronized (remoteSones) {
- final Sone sone = getRemoteSone(identity.getId(), true).setIdentity(identity);
- boolean newSone = sone.getRequestUri() == null;
- sone.setRequestUri(getSoneUri(identity.getRequestUri()));
- sone.setLatestEdition(Numbers.safeParseLong(identity.getProperty("Sone.LatestEdition"), (long) 0));
+ final Sone sone = getRemoteSone(identity.getId(), true).setIdentity(identity);
+ boolean newSone = sone.getRequestUri() == null;
+ sone.setRequestUri(getSoneUri(identity.getRequestUri()));
+ sone.setLatestEdition(Numbers.safeParseLong(identity.getProperty("Sone.LatestEdition"), (long) 0));
+ if (newSone) {
+ synchronized (knownSones) {
+ newSone = !knownSones.contains(sone.getId());
+ }
+ sone.setKnown(!newSone);
if (newSone) {
- synchronized (knownSones) {
- newSone = !knownSones.contains(sone.getId());
- }
- sone.setKnown(!newSone);
- if (newSone) {
- coreListenerManager.fireNewSoneFound(sone);
- for (Sone localSone : getLocalSones()) {
- if (localSone.getOptions().getBooleanOption("AutoFollow").get()) {
- followSone(localSone, sone);
- }
+ coreListenerManager.fireNewSoneFound(sone);
+ for (Sone localSone : getLocalSones()) {
+ if (localSone.getOptions().getBooleanOption("AutoFollow").get()) {
+ followSone(localSone, sone);
}
}
}
- soneDownloader.addSone(sone);
- soneDownloaders.execute(new Runnable() {
+ }
+ soneDownloader.addSone(sone);
+ soneDownloaders.execute(new Runnable() {
- @Override
- @SuppressWarnings("synthetic-access")
- public void run() {
- soneDownloader.fetchSone(sone, sone.getRequestUri());
- }
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() {
+ soneDownloader.fetchSone(sone, sone.getRequestUri());
+ }
- });
- return sone;
- }
+ });
+ database.saveSone(sone);
+ return sone;
}
/**
}
/**
- * Retrieves the trust relationship from the origin to the target. If the
- * trust relationship can not be retrieved, {@code null} is returned.
- *
- * @see Identity#getTrust(OwnIdentity)
- * @param origin
- * The origin of the trust tree
- * @param target
- * The target of the trust
- * @return The trust relationship
- */
- public Trust getTrust(Sone origin, Sone target) {
- if (!origin.isLocal()) {
- logger.log(Level.WARNING, String.format("Tried to get trust from remote Sone: %s", origin));
- return null;
- }
- return target.getIdentity().getTrust((OwnIdentity) origin.getIdentity());
- }
-
- /**
-- * Sets the trust value of the given origin Sone for the target Sone.
++ * Sets the trust value of the given origin Sone for
++ * the target Sone.
*
* @param origin
* The origin Sone
*/
public void setTrust(Sone origin, Sone target, int trustValue) {
Validation.begin().isNotNull("Trust Origin", origin).check().isInstanceOf("Trust Origin", origin.getIdentity(), OwnIdentity.class).isNotNull("Trust Target", target).isLessOrEqual("Trust Value", trustValue, 100).isGreaterOrEqual("Trust Value", trustValue, -100).check();
- try {
- ((OwnIdentity) origin.getIdentity()).setTrust(target.getIdentity(), trustValue, preferences.getTrustComment());
- } catch (WebOfTrustException wote1) {
- logger.log(Level.WARNING, String.format("Could not set trust for Sone: %s", target), wote1);
- }
+ webOfTrustUpdater.setTrust((OwnIdentity) origin.getIdentity(), target.getIdentity(), trustValue, preferences.getTrustComment());
}
/**
*/
public void removeTrust(Sone origin, Sone target) {
Validation.begin().isNotNull("Trust Origin", origin).isNotNull("Trust Target", target).check().isInstanceOf("Trust Origin Identity", origin.getIdentity(), OwnIdentity.class).check();
- try {
- ((OwnIdentity) origin.getIdentity()).removeTrust(target.getIdentity());
- } catch (WebOfTrustException wote1) {
- logger.log(Level.WARNING, String.format("Could not remove trust for Sone: %s", target), wote1);
- }
+ webOfTrustUpdater.setTrust((OwnIdentity) origin.getIdentity(), target.getIdentity(), null, null);
}
/**
logger.log(Level.WARNING, String.format("Tried to delete Sone of non-own identity: %s", sone));
return;
}
- synchronized (localSones) {
- if (!localSones.containsKey(sone.getId())) {
- logger.log(Level.WARNING, String.format("Tried to delete non-local Sone: %s", sone));
- return;
- }
- localSones.remove(sone.getId());
- SoneInserter soneInserter = soneInserters.remove(sone);
- soneInserter.removeSoneInsertListener(this);
- soneInserter.stop();
+ if (!sone.isLocal()) {
+ logger.log(Level.WARNING, String.format("Tried to delete non-local Sone: %s", sone));
+ return;
}
- try {
- ((OwnIdentity) sone.getIdentity()).removeContext("Sone");
- ((OwnIdentity) sone.getIdentity()).removeProperty("Sone.LatestEdition");
- } catch (WebOfTrustException wote1) {
- logger.log(Level.WARNING, String.format("Could not remove context and properties from Sone: %s", sone), wote1);
- }
+ database.removeSone(sone.getId());
+ SoneInserter soneInserter = soneInserters.remove(sone);
+ soneInserter.removeSoneInsertListener(this);
+ soneInserter.stop();
+ webOfTrustUpdater.removeContext((OwnIdentity) sone.getIdentity(), "Sone");
+ webOfTrustUpdater.removeProperty((OwnIdentity) sone.getIdentity(), "Sone.LatestEdition");
try {
configuration.getLongValue("Sone/" + sone.getId() + "/Time").setValue(null);
} catch (ConfigurationException ce1) {
* The Sone to load and update
*/
public void loadSone(Sone sone) {
- if (!isLocalSone(sone)) {
+ if (!sone.isLocal()) {
logger.log(Level.FINE, String.format("Tried to load non-local Sone: %s", sone));
return;
}
logger.log(Level.WARNING, "Invalid post found, aborting load!");
return;
}
- Post post = getPost(postId).setSone(sone).setTime(postTime).setText(postText);
+ Post post = getPost(postId, true).setSone(sone).setTime(postTime).setText(postText);
if ((postRecipientId != null) && (postRecipientId.length() == 43)) {
post.setRecipient(getSone(postRecipientId));
}
logger.log(Level.WARNING, "Invalid reply found, aborting load!");
return;
}
- replies.add(getReply(replyId).setSone(sone).setPost(getPost(postId)).setTime(replyTime).setText(replyText));
+ replies.add(getReply(replyId).setSone(sone).setPost(getPost(postId, true)).setTime(replyTime).setText(replyText));
}
/* load post likes. */
*
* @param sone
* The Sone that creates the post
- * @param text
- * The text of the post
- * @return The created post
- */
- public Post createPost(Sone sone, String text) {
- return createPost(sone, System.currentTimeMillis(), text);
- }
-
- /**
- * Creates a new post.
- *
- * @param sone
- * The Sone that creates the post
- * @param time
- * The time of the post
- * @param text
- * The text of the post
- * @return The created post
- */
- public Post createPost(Sone sone, long time, String text) {
- return createPost(sone, null, time, text);
- }
-
- /**
- * Creates a new post.
- *
- * @param sone
- * The Sone that creates the post
- * @param recipient
- * The recipient Sone, or {@code null} if this post does not have
- * a recipient
- * @param text
- * The text of the post
- * @return The created post
- */
- public Post createPost(Sone sone, Sone recipient, String text) {
- return createPost(sone, recipient, System.currentTimeMillis(), text);
- }
-
- /**
- * Creates a new post.
- *
- * @param sone
- * The Sone that creates the post
* @param recipient
* The recipient Sone, or {@code null} if this post does not have
* a recipient
* @return The created post
*/
public Post createPost(Sone sone, Sone recipient, long time, String text) {
- if (!isLocalSone(sone)) {
+ if (!sone.isLocal()) {
logger.log(Level.FINE, String.format("Tried to create post for non-local Sone: %s", sone));
return null;
}
- final Post post = new Post(sone, time, text);
+ final Post post = new PostImpl(sone, time, text);
if (recipient != null) {
post.setRecipient(recipient);
}
* The post to delete
*/
public void deletePost(Post post) {
- if (!isLocalSone(post.getSone())) {
+ if (!post.getSone().isLocal()) {
logger.log(Level.WARNING, String.format("Tried to delete post of non-local Sone: %s", post.getSone()));
return;
}
* @return The created reply
*/
public PostReply createReply(Sone sone, Post post, long time, String text) {
- if (!isLocalSone(sone)) {
+ if (!sone.isLocal()) {
logger.log(Level.FINE, String.format("Tried to create reply for non-local Sone: %s", sone));
return null;
}
*/
public void deleteReply(PostReply reply) {
Sone sone = reply.getSone();
- if (!isLocalSone(sone)) {
+ if (!sone.isLocal()) {
logger.log(Level.FINE, String.format("Tried to delete non-local reply: %s", reply));
return;
}
* The album to remove
*/
public void deleteAlbum(Album album) {
- Validation.begin().isNotNull("Album", album).check().is("Local Sone", isLocalSone(album.getSone())).check();
+ Validation.begin().isNotNull("Album", album).check().is("Local Sone", album.getSone().isLocal()).check();
if (!album.isEmpty()) {
return;
}
synchronized (albums) {
albums.remove(album.getId());
}
- saveSone(album.getSone());
+ touchConfiguration();
}
/**
* @return The newly created image
*/
public Image createImage(Sone sone, Album album, TemporaryImage temporaryImage) {
- Validation.begin().isNotNull("Sone", sone).isNotNull("Album", album).isNotNull("Temporary Image", temporaryImage).check().is("Local Sone", isLocalSone(sone)).check().isEqual("Owner and Album Owner", sone, album.getSone()).check();
+ Validation.begin().isNotNull("Sone", sone).isNotNull("Album", album).isNotNull("Temporary Image", temporaryImage).check().is("Local Sone", sone.isLocal()).check().isEqual("Owner and Album Owner", sone, album.getSone()).check();
Image image = new Image(temporaryImage.getId()).setSone(sone).setCreationTime(System.currentTimeMillis());
album.addImage(image);
synchronized (images) {
* The image to delete
*/
public void deleteImage(Image image) {
- Validation.begin().isNotNull("Image", image).check().is("Local Sone", isLocalSone(image.getSone())).check();
+ Validation.begin().isNotNull("Image", image).check().is("Local Sone", image.getSone().isLocal()).check();
deleteTemporaryImage(image.getId());
image.getAlbum().removeImage(image);
synchronized (images) {
images.remove(image.getId());
}
- saveSone(image.getSone());
+ touchConfiguration();
}
/**
loadConfiguration();
updateChecker.addUpdateListener(this);
updateChecker.start();
+ webOfTrustUpdater.start();
}
/**
*/
@Override
public void serviceStop() {
- for (SoneInserter soneInserter : soneInserters.values()) {
- soneInserter.removeSoneInsertListener(this);
- soneInserter.stop();
- synchronized (localSones) {
- for (Entry<Sone, SoneInserter> soneInserter : soneInserters.entrySet()) {
- soneInserter.getValue().removeSoneInsertListener(this);
- soneInserter.getValue().stop();
- saveSone(soneInserter.getKey());
- }
++ for (Entry<Sone, SoneInserter> soneInserter : soneInserters.entrySet()) {
++ soneInserter.getValue().removeSoneInsertListener(this);
++ soneInserter.getValue().stop();
++ saveSone(soneInserter.getKey());
}
+ saveConfiguration();
+ webOfTrustUpdater.stop();
updateChecker.stop();
updateChecker.removeUpdateListener(this);
soneDownloader.stop();
* The Sone to save
*/
private synchronized void saveSone(Sone sone) {
- if (!isLocalSone(sone)) {
+ if (!sone.isLocal()) {
logger.log(Level.FINE, String.format("Tried to save non-local Sone: %s", sone));
return;
}
configuration.save();
- ((OwnIdentity) sone.getIdentity()).setProperty("Sone.LatestEdition", String.valueOf(sone.getLatestEdition()));
+ webOfTrustUpdater.setProperty((OwnIdentity) sone.getIdentity(), "Sone.LatestEdition", String.valueOf(sone.getLatestEdition()));
logger.log(Level.INFO, String.format("Sone %s saved.", sone));
} catch (ConfigurationException ce1) {
logger.log(Level.WARNING, String.format("Could not save Sone: %s", sone), ce1);
- } catch (WebOfTrustException wote1) {
- logger.log(Level.WARNING, String.format("Could not set WoT property for Sone: %s", sone), wote1);
}
}
configuration.getIntValue("Option/ConfigurationVersion").setValue(0);
configuration.getIntValue("Option/InsertionDelay").setValue(options.getIntegerOption("InsertionDelay").getReal());
configuration.getIntValue("Option/PostsPerPage").setValue(options.getIntegerOption("PostsPerPage").getReal());
+ configuration.getIntValue("Option/ImagesPerPage").setValue(options.getIntegerOption("ImagesPerPage").getReal());
configuration.getIntValue("Option/CharactersPerPost").setValue(options.getIntegerOption("CharactersPerPost").getReal());
configuration.getIntValue("Option/PostCutOffLength").setValue(options.getIntegerOption("PostCutOffLength").getReal());
configuration.getBooleanValue("Option/RequireFullAccess").setValue(options.getBooleanOption("RequireFullAccess").getReal());
configuration.getStringValue("Option/TrustComment").setValue(options.getStringOption("TrustComment").getReal());
configuration.getBooleanValue("Option/ActivateFcpInterface").setValue(options.getBooleanOption("ActivateFcpInterface").getReal());
configuration.getIntValue("Option/FcpFullAccessRequired").setValue(options.getIntegerOption("FcpFullAccessRequired").getReal());
- configuration.getBooleanValue("Option/SoneRescueMode").setValue(options.getBooleanOption("SoneRescueMode").getReal());
- configuration.getBooleanValue("Option/ClearOnNextRestart").setValue(options.getBooleanOption("ClearOnNextRestart").getReal());
- configuration.getBooleanValue("Option/ReallyClearOnNextRestart").setValue(options.getBooleanOption("ReallyClearOnNextRestart").getReal());
/* save known Sones. */
int soneCounter = 0;
}));
options.addIntegerOption("PostsPerPage", new DefaultOption<Integer>(10, new IntegerRangeValidator(1, Integer.MAX_VALUE)));
+ options.addIntegerOption("ImagesPerPage", new DefaultOption<Integer>(9, new IntegerRangeValidator(1, Integer.MAX_VALUE)));
options.addIntegerOption("CharactersPerPost", new DefaultOption<Integer>(400, new OrValidator<Integer>(new IntegerRangeValidator(50, Integer.MAX_VALUE), new EqualityValidator<Integer>(-1))));
options.addIntegerOption("PostCutOffLength", new DefaultOption<Integer>(200, new OrValidator<Integer>(new IntegerRangeValidator(50, Integer.MAX_VALUE), new EqualityValidator<Integer>(-1))));
options.addBooleanOption("RequireFullAccess", new DefaultOption<Boolean>(false));
}
}));
- options.addBooleanOption("SoneRescueMode", new DefaultOption<Boolean>(false));
- options.addBooleanOption("ClearOnNextRestart", new DefaultOption<Boolean>(false));
- options.addBooleanOption("ReallyClearOnNextRestart", new DefaultOption<Boolean>(false));
-
- /* read options from configuration. */
- options.getBooleanOption("ClearOnNextRestart").set(configuration.getBooleanValue("Option/ClearOnNextRestart").getValue(null));
- options.getBooleanOption("ReallyClearOnNextRestart").set(configuration.getBooleanValue("Option/ReallyClearOnNextRestart").getValue(null));
- boolean clearConfiguration = options.getBooleanOption("ClearOnNextRestart").get() && options.getBooleanOption("ReallyClearOnNextRestart").get();
- options.getBooleanOption("ClearOnNextRestart").set(null);
- options.getBooleanOption("ReallyClearOnNextRestart").set(null);
- if (clearConfiguration) {
- /* stop loading the configuration. */
- return;
- }
loadConfigurationValue("InsertionDelay");
loadConfigurationValue("PostsPerPage");
+ loadConfigurationValue("ImagesPerPage");
loadConfigurationValue("CharactersPerPost");
loadConfigurationValue("PostCutOffLength");
options.getBooleanOption("RequireFullAccess").set(configuration.getBooleanValue("Option/RequireFullAccess").getValue(null));
options.getStringOption("TrustComment").set(configuration.getStringValue("Option/TrustComment").getValue(null));
options.getBooleanOption("ActivateFcpInterface").set(configuration.getBooleanValue("Option/ActivateFcpInterface").getValue(null));
options.getIntegerOption("FcpFullAccessRequired").set(configuration.getIntValue("Option/FcpFullAccessRequired").getValue(null));
- options.getBooleanOption("SoneRescueMode").set(configuration.getBooleanValue("Option/SoneRescueMode").getValue(null));
/* load known Sones. */
int soneCounter = 0;
* The URI to derive the Sone URI from
* @return The derived URI
*/
- private FreenetURI getSoneUri(String uriString) {
+ private static FreenetURI getSoneUri(String uriString) {
try {
FreenetURI uri = new FreenetURI(uriString).setDocName("Sone").setMetaString(new String[0]);
return uri;
} catch (MalformedURLException mue1) {
- logger.log(Level.WARNING, String.format("Could not create Sone URI from URI: %s", uriString, mue1));
+ logger.log(Level.WARNING, String.format("Could not create Sone URI from URI: %s", uriString), mue1);
return null;
}
}
}
}
}
- synchronized (remoteSones) {
- remoteSones.remove(identity.getId());
- }
+ database.removeSone(identity.getId());
coreListenerManager.fireSoneRemoved(sone);
}
logger.log(Level.WARNING, String.format("Image insert finished for %s: %s", image, key));
image.setKey(key.toString());
deleteTemporaryImage(image.getId());
- saveSone(image.getSone());
+ touchConfiguration();
coreListenerManager.fireImageInsertFinished(image);
}
}
/**
+ * Returns the number of images to show per page.
+ *
+ * @return The number of images to show per page
+ */
+ public int getImagesPerPage() {
+ return options.getIntegerOption("ImagesPerPage").get();
+ }
+
+ /**
+ * Validates the number of images per page.
+ *
+ * @param imagesPerPage
+ * The number of images per page
+ * @return {@code true} if the number of images per page was valid,
+ * {@code false} otherwise
+ */
+ public boolean validateImagesPerPage(Integer imagesPerPage) {
+ return options.getIntegerOption("ImagesPerPage").validate(imagesPerPage);
+ }
+
+ /**
+ * Sets the number of images per page.
+ *
+ * @param imagesPerPage
+ * The number of images per page
+ * @return This preferences object
+ */
+ public Preferences setImagesPerPage(Integer imagesPerPage) {
+ options.getIntegerOption("ImagesPerPage").set(imagesPerPage);
+ return this;
+ }
+
+ /**
* Returns the number of characters per post, or <code>-1</code> if the
* posts should not be cut off.
*
return this;
}
- /**
- * Returns whether Sone should clear its settings on the next restart.
- * In order to be effective, {@link #isReallyClearOnNextRestart()} needs
- * to return {@code true} as well!
- *
- * @return {@code true} if Sone should clear its settings on the next
- * restart, {@code false} otherwise
- */
- public boolean isClearOnNextRestart() {
- return options.getBooleanOption("ClearOnNextRestart").get();
- }
-
- /**
- * Sets whether Sone will clear its settings on the next restart.
- *
- * @param clearOnNextRestart
- * {@code true} if Sone should clear its settings on the next
- * restart, {@code false} otherwise
- * @return This preferences
- */
- public Preferences setClearOnNextRestart(Boolean clearOnNextRestart) {
- options.getBooleanOption("ClearOnNextRestart").set(clearOnNextRestart);
- return this;
- }
-
- /**
- * Returns whether Sone should really clear its settings on next
- * restart. This is a confirmation option that needs to be set in
- * addition to {@link #isClearOnNextRestart()} in order to clear Sone’s
- * settings on the next restart.
- *
- * @return {@code true} if Sone should really clear its settings on the
- * next restart, {@code false} otherwise
- */
- public boolean isReallyClearOnNextRestart() {
- return options.getBooleanOption("ReallyClearOnNextRestart").get();
- }
-
- /**
- * Sets whether Sone should really clear its settings on the next
- * restart.
- *
- * @param reallyClearOnNextRestart
- * {@code true} if Sone should really clear its settings on
- * the next restart, {@code false} otherwise
- * @return This preferences
- */
- public Preferences setReallyClearOnNextRestart(Boolean reallyClearOnNextRestart) {
- options.getBooleanOption("ReallyClearOnNextRestart").set(reallyClearOnNextRestart);
- return this;
- }
-
}
}
--- /dev/null
- albums.add(album);
+/*
+ * Sone - MemorySone.java - Copyright © 2010–2012 David Roden
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.sone.database.memory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import net.pterodactylus.sone.core.Options;
+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.Reply;
+import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.database.Database;
+import net.pterodactylus.sone.freenet.wot.Identity;
+import net.pterodactylus.util.logging.Logging;
+import net.pterodactylus.util.validation.Validation;
+import freenet.keys.FreenetURI;
+
+/**
+ * Implementation of a {@link Sone} that keeps all added data in memory. A
+ * self-created instance of this class should be converted to a {@link Database}
+ * -based instance of {@link Sone} as soon as possible (unless it was returned
+ * by a {@link MemoryDatabase}).
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class MemorySone implements Sone {
+
+ /** The logger. */
+ private static final Logger logger = Logging.getLogger(Sone.class);
+
+ /** The ID of this Sone. */
+ private final String id;
+
+ /** Whether this is a local Sone. */
+ private final boolean local;
+
+ /** The identity of this Sone. */
+ private Identity identity;
+
+ /** The URI under which the Sone is stored in Freenet. */
+ private volatile FreenetURI requestUri;
+
+ /** The URI used to insert a new version of this Sone. */
+ /* This will be null for remote Sones! */
+ private volatile FreenetURI insertUri;
+
+ /** The latest edition of the Sone. */
+ private volatile long latestEdition;
+
+ /** The time of the last inserted update. */
+ private volatile long time;
+
+ /** The status of this Sone. */
+ private volatile SoneStatus status = SoneStatus.unknown;
+
+ /** The profile of this Sone. */
+ private volatile Profile profile = new Profile(this);
+
+ /** The client used by the Sone. */
+ private volatile Client client;
+
+ /** Whether this Sone is known. */
+ private volatile boolean known;
+
+ /** All friend Sones. */
+ private final Set<String> friendSones = new CopyOnWriteArraySet<String>();
+
+ /** All posts. */
+ private final Set<Post> posts = new CopyOnWriteArraySet<Post>();
+
+ /** All replies. */
+ private final Set<PostReply> replies = new CopyOnWriteArraySet<PostReply>();
+
+ /** The IDs of all liked posts. */
+ private final Set<String> likedPostIds = new CopyOnWriteArraySet<String>();
+
+ /** The IDs of all liked replies. */
+ private final Set<String> likedReplyIds = new CopyOnWriteArraySet<String>();
+
+ /** The albums of this Sone. */
+ private final List<Album> albums = new CopyOnWriteArrayList<Album>();
+
+ /** Sone-specific options. */
+ private final Options options = new Options();
+
+ /**
+ * Creates a new Sone.
+ *
+ * @param id
+ * The ID of the Sone
+ * @param local
+ * {@code true} if this Sone is local, {@code false} otherwise
+ */
+ public MemorySone(String id, boolean local) {
+ this.id = id;
+ this.local = local;
+ }
+
+ //
+ // ACCESSORS
+ //
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Identity getIdentity() {
+ return identity;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone setIdentity(Identity identity) throws IllegalArgumentException {
+ if (!identity.getId().equals(id)) {
+ throw new IllegalArgumentException("Identity’s ID does not match Sone’s ID!");
+ }
+ this.identity = identity;
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isLocal() {
+ return local;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getName() {
+ return (identity != null) ? identity.getNickname() : null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public FreenetURI getRequestUri() {
+ return (requestUri != null) ? requestUri.setSuggestedEdition(latestEdition) : null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone setRequestUri(FreenetURI requestUri) {
+ if (this.requestUri == null) {
+ this.requestUri = requestUri.setKeyType("USK").setDocName("Sone").setMetaString(new String[0]);
+ return this;
+ }
+ if (!this.requestUri.equalsKeypair(requestUri)) {
+ logger.log(Level.WARNING, String.format("Request URI %s tried to overwrite %s!", requestUri, this.requestUri));
+ return this;
+ }
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public FreenetURI getInsertUri() {
+ return (insertUri != null) ? insertUri.setSuggestedEdition(latestEdition) : null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone setInsertUri(FreenetURI insertUri) {
+ if (this.insertUri == null) {
+ this.insertUri = insertUri.setKeyType("USK").setDocName("Sone").setMetaString(new String[0]);
+ return this;
+ }
+ if (!this.insertUri.equalsKeypair(insertUri)) {
+ logger.log(Level.WARNING, String.format("Request URI %s tried to overwrite %s!", insertUri, this.insertUri));
+ return this;
+ }
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public long getLatestEdition() {
+ return latestEdition;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setLatestEdition(long latestEdition) {
+ if (!(latestEdition > this.latestEdition)) {
+ logger.log(Level.FINE, String.format("New latest edition %d is not greater than current latest edition %d!", latestEdition, this.latestEdition));
+ return;
+ }
+ this.latestEdition = latestEdition;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public long getTime() {
+ return time;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone setTime(long time) {
+ this.time = time;
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public SoneStatus getStatus() {
+ return status;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone setStatus(SoneStatus status) {
+ Validation.begin().isNotNull("Sone Status", status).check();
+ this.status = status;
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Profile getProfile() {
+ return new Profile(profile);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setProfile(Profile profile) {
+ this.profile = new Profile(profile);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Client getClient() {
+ return client;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone setClient(Client client) {
+ this.client = client;
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isKnown() {
+ return known;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone setKnown(boolean known) {
+ this.known = known;
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<String> getFriends() {
+ List<String> friends = new ArrayList<String>(friendSones);
+ return friends;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean hasFriend(String friendSoneId) {
+ return friendSones.contains(friendSoneId);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone addFriend(String friendSone) {
+ if (!friendSone.equals(id)) {
+ friendSones.add(friendSone);
+ }
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone removeFriend(String friendSoneId) {
+ friendSones.remove(friendSoneId);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<Post> getPosts() {
+ List<Post> sortedPosts;
+ synchronized (this) {
+ sortedPosts = new ArrayList<Post>(posts);
+ }
+ Collections.sort(sortedPosts, Post.TIME_COMPARATOR);
+ return sortedPosts;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone setPosts(Collection<Post> posts) {
+ synchronized (this) {
+ this.posts.clear();
+ this.posts.addAll(posts);
+ }
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addPost(Post post) {
+ if (post.getSone().equals(this) && posts.add(post)) {
+ logger.log(Level.FINEST, String.format("Adding %s to “%s”.", post, getName()));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removePost(Post post) {
+ if (post.getSone().equals(this)) {
+ posts.remove(post);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<PostReply> getReplies() {
+ return Collections.unmodifiableSet(replies);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone setReplies(Collection<PostReply> replies) {
+ this.replies.clear();
+ this.replies.addAll(replies);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addReply(PostReply reply) {
+ if (reply.getSone().equals(this)) {
+ replies.add(reply);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeReply(PostReply reply) {
+ if (reply.getSone().equals(this)) {
+ replies.remove(reply);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<String> getLikedPostIds() {
+ return Collections.unmodifiableSet(likedPostIds);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone setLikePostIds(Set<String> likedPostIds) {
+ this.likedPostIds.clear();
+ this.likedPostIds.addAll(likedPostIds);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isLikedPostId(String postId) {
+ return likedPostIds.contains(postId);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone addLikedPostId(String postId) {
+ likedPostIds.add(postId);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone removeLikedPostId(String postId) {
+ likedPostIds.remove(postId);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<String> getLikedReplyIds() {
+ return Collections.unmodifiableSet(likedReplyIds);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone setLikeReplyIds(Set<String> likedReplyIds) {
+ this.likedReplyIds.clear();
+ this.likedReplyIds.addAll(likedReplyIds);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isLikedReplyId(String replyId) {
+ return likedReplyIds.contains(replyId);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone addLikedReplyId(String replyId) {
+ likedReplyIds.add(replyId);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone removeLikedReplyId(String replyId) {
+ likedReplyIds.remove(replyId);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<Album> getAlbums() {
+ return Collections.unmodifiableList(albums);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<Album> getAllAlbums() {
+ List<Album> flatAlbums = new ArrayList<Album>();
+ flatAlbums.addAll(albums);
+ int lastAlbumIndex = 0;
+ while (lastAlbumIndex < flatAlbums.size()) {
+ int previousAlbumCount = flatAlbums.size();
+ for (Album album : new ArrayList<Album>(flatAlbums.subList(lastAlbumIndex, flatAlbums.size()))) {
+ flatAlbums.addAll(album.getAlbums());
+ }
+ lastAlbumIndex = previousAlbumCount;
+ }
+ return flatAlbums;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<Image> getAllImages() {
+ List<Image> allImages = new ArrayList<Image>();
+ for (Album album : getAllAlbums()) {
+ allImages.addAll(album.getImages());
+ }
+ return allImages;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addAlbum(Album album) {
+ Validation.begin().isNotNull("Album", album).check().isEqual("Album Owner", album.getSone(), this).check();
++ if (!albums.contains(album)) {
++ albums.add(album);
++ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setAlbums(Collection<? extends Album> albums) {
+ Validation.begin().isNotNull("Albums", albums).check();
+ this.albums.clear();
+ for (Album album : albums) {
+ addAlbum(album);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeAlbum(Album album) {
+ Validation.begin().isNotNull("Album", album).check().isEqual("Album Owner", album.getSone(), this).check();
+ albums.remove(album);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Album moveAlbumUp(Album album) {
+ Validation.begin().isNotNull("Album", album).check().isEqual("Album Owner", album.getSone(), this).isNull("Album Parent", album.getParent()).check();
+ int oldIndex = albums.indexOf(album);
+ if (oldIndex <= 0) {
+ return null;
+ }
+ albums.remove(oldIndex);
+ albums.add(oldIndex - 1, album);
+ return albums.get(oldIndex);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Album moveAlbumDown(Album album) {
+ Validation.begin().isNotNull("Album", album).check().isEqual("Album Owner", album.getSone(), this).isNull("Album Parent", album.getParent()).check();
+ int oldIndex = albums.indexOf(album);
+ if ((oldIndex < 0) || (oldIndex >= (albums.size() - 1))) {
+ return null;
+ }
+ albums.remove(oldIndex);
+ albums.add(oldIndex + 1, album);
+ return albums.get(oldIndex);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Options getOptions() {
+ return options;
+ }
+
+ //
+ // FINGERPRINTABLE METHODS
+ //
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized String getFingerprint() {
+ StringBuilder fingerprint = new StringBuilder();
+ fingerprint.append(profile.getFingerprint());
+
+ fingerprint.append("Posts(");
+ for (Post post : getPosts()) {
+ fingerprint.append("Post(").append(post.getId()).append(')');
+ }
+ fingerprint.append(")");
+
+ List<PostReply> replies = new ArrayList<PostReply>(getReplies());
+ Collections.sort(replies, Reply.TIME_COMPARATOR);
+ fingerprint.append("Replies(");
+ for (PostReply reply : replies) {
+ fingerprint.append("Reply(").append(reply.getId()).append(')');
+ }
+ fingerprint.append(')');
+
+ List<String> likedPostIds = new ArrayList<String>(getLikedPostIds());
+ Collections.sort(likedPostIds);
+ fingerprint.append("LikedPosts(");
+ for (String likedPostId : likedPostIds) {
+ fingerprint.append("Post(").append(likedPostId).append(')');
+ }
+ fingerprint.append(')');
+
+ List<String> likedReplyIds = new ArrayList<String>(getLikedReplyIds());
+ Collections.sort(likedReplyIds);
+ fingerprint.append("LikedReplies(");
+ for (String likedReplyId : likedReplyIds) {
+ fingerprint.append("Reply(").append(likedReplyId).append(')');
+ }
+ fingerprint.append(')');
+
+ fingerprint.append("Albums(");
+ for (Album album : albums) {
+ fingerprint.append(album.getFingerprint());
+ }
+ fingerprint.append(')');
+
+ return fingerprint.toString();
+ }
+
+ //
+ // INTERFACE Comparable<Sone>
+ //
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int compareTo(Sone sone) {
+ return NICE_NAME_COMPARATOR.compare(this, sone);
+ }
+
+ //
+ // OBJECT METHODS
+ //
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (!(object instanceof Sone)) {
+ return false;
+ }
+ return ((Sone) object).getId().equals(id);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return getClass().getName() + "[identity=" + identity + ",requestUri=" + requestUri + ",insertUri(" + String.valueOf(insertUri).length() + "),friends(" + friendSones.size() + "),posts(" + posts.size() + "),replies(" + replies.size() + ")]";
+ }
+
+}
import net.pterodactylus.sone.core.Core;
import net.pterodactylus.sone.core.FreenetInterface;
+ import net.pterodactylus.sone.core.WebOfTrustUpdater;
+import net.pterodactylus.sone.database.Database;
+import net.pterodactylus.sone.database.memory.MemoryDatabase;
import net.pterodactylus.sone.fcp.FcpInterface;
import net.pterodactylus.sone.freenet.PluginStoreConfigurationBackend;
import net.pterodactylus.sone.freenet.plugin.PluginConnector;
}
/** The version. */
- public static final Version VERSION = new Version(0, 8, 1);
+ public static final Version VERSION = new Version(0, 8, 2);
/** The logger. */
private static final Logger logger = Logging.getLogger(SonePlugin.class);
identityManager = new IdentityManager(webOfTrustConnector);
identityManager.setContext("Sone");
+ /* create Sone database. */
+ Database soneDatabase = new MemoryDatabase();
+
+ /* create trust updater. */
+ WebOfTrustUpdater trustUpdater = new WebOfTrustUpdater(webOfTrustConnector);
+ trustUpdater.init();
+
/* create core. */
- core = new Core(oldConfiguration, soneDatabase, freenetInterface, identityManager);
- core = new Core(oldConfiguration, freenetInterface, identityManager, trustUpdater);
++ core = new Core(oldConfiguration, soneDatabase, freenetInterface, identityManager, trustUpdater);
/* create the web interface. */
webInterface = new WebInterface(this);
import net.pterodactylus.sone.data.Profile;
import net.pterodactylus.sone.data.Sone;
import net.pterodactylus.sone.data.Sone.ShowCustomAvatars;
+ import net.pterodactylus.sone.freenet.wot.OwnIdentity;
import net.pterodactylus.sone.freenet.wot.Trust;
import net.pterodactylus.util.template.Accessor;
import net.pterodactylus.util.template.ReflectionAccessor;
return null;
}
Sone remoteSone = profile.getSone();
- if (core.isLocalSone(remoteSone)) {
+ if (remoteSone.isLocal()) {
/* always show your own avatars. */
return avatarId;
}
if (showCustomAvatars == ShowCustomAvatars.FOLLOWED) {
return currentSone.hasFriend(remoteSone.getId()) ? avatarId : null;
}
- Trust trust = core.getTrust(currentSone, remoteSone);
+ Trust trust = remoteSone.getIdentity().getTrust((OwnIdentity) currentSone.getIdentity());
if (trust == null) {
return null;
}
import net.pterodactylus.sone.data.Profile;
import net.pterodactylus.sone.data.Sone;
import net.pterodactylus.sone.data.Sone.SoneStatus;
+ import net.pterodactylus.sone.freenet.wot.OwnIdentity;
import net.pterodactylus.sone.freenet.wot.Trust;
import net.pterodactylus.sone.web.WebInterface;
import net.pterodactylus.sone.web.ajax.GetTimesAjaxPage;
Sone sone = (Sone) object;
if (member.equals("niceName")) {
return getNiceName(sone);
- } else if (member.equals("local")) {
- return core.isLocalSone(sone);
} else if (member.equals("friend")) {
Sone currentSone = (Sone) templateContext.get("currentSone");
return (currentSone != null) && currentSone.hasFriend(sone.getId());
if (currentSone == null) {
return null;
}
- Trust trust = core.getTrust(currentSone, sone);
+ Trust trust = sone.getIdentity().getTrust((OwnIdentity) currentSone.getIdentity());
logger.log(Level.FINEST, String.format("Trust for %s by %s: %s", sone, currentSone, trust));
if (trust == null) {
return new Trust(null, null, null);
import net.pterodactylus.sone.core.SoneProvider;
import net.pterodactylus.sone.data.Post;
import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.database.memory.MemorySone;
+ import net.pterodactylus.util.io.Closer;
import net.pterodactylus.util.logging.Logging;
import freenet.keys.FreenetURI;
public Iterable<Part> parse(SoneTextParserContext context, Reader source) throws IOException {
PartContainer parts = new PartContainer();
BufferedReader bufferedReader = (source instanceof BufferedReader) ? (BufferedReader) source : new BufferedReader(source);
- String line;
- boolean lastLineEmpty = true;
- int emptyLines = 0;
- while ((line = bufferedReader.readLine()) != null) {
- if (line.trim().length() == 0) {
- if (lastLineEmpty) {
+ try {
+ String line;
+ boolean lastLineEmpty = true;
+ int emptyLines = 0;
+ while ((line = bufferedReader.readLine()) != null) {
+ if (line.trim().length() == 0) {
+ if (lastLineEmpty) {
+ continue;
+ }
+ parts.add(new PlainTextPart("\n"));
+ ++emptyLines;
+ lastLineEmpty = emptyLines == 2;
continue;
}
- parts.add(new PlainTextPart("\n"));
- ++emptyLines;
- lastLineEmpty = emptyLines == 2;
- continue;
- }
- emptyLines = 0;
- /*
- * lineComplete tracks whether the block you are parsing is the
- * first block of the line. this is important because sometimes you
- * have to add an additional line break.
- */
- boolean lineComplete = true;
- while (line.length() > 0) {
- int nextKsk = line.indexOf("KSK@");
- int nextChk = line.indexOf("CHK@");
- int nextSsk = line.indexOf("SSK@");
- int nextUsk = line.indexOf("USK@");
- int nextHttp = line.indexOf("http://");
- int nextHttps = line.indexOf("https://");
- int nextSone = line.indexOf("sone://");
- int nextPost = line.indexOf("post://");
- if ((nextKsk == -1) && (nextChk == -1) && (nextSsk == -1) && (nextUsk == -1) && (nextHttp == -1) && (nextHttps == -1) && (nextSone == -1) && (nextPost == -1)) {
- if (lineComplete && !lastLineEmpty) {
- parts.add(new PlainTextPart("\n" + line));
- } else {
- parts.add(new PlainTextPart(line));
+ emptyLines = 0;
+ /*
+ * lineComplete tracks whether the block you are parsing is the
+ * first block of the line. this is important because sometimes
+ * you have to add an additional line break.
+ */
+ boolean lineComplete = true;
+ while (line.length() > 0) {
+ int nextKsk = line.indexOf("KSK@");
+ int nextChk = line.indexOf("CHK@");
+ int nextSsk = line.indexOf("SSK@");
+ int nextUsk = line.indexOf("USK@");
+ int nextHttp = line.indexOf("http://");
+ int nextHttps = line.indexOf("https://");
+ int nextSone = line.indexOf("sone://");
+ int nextPost = line.indexOf("post://");
+ if ((nextKsk == -1) && (nextChk == -1) && (nextSsk == -1) && (nextUsk == -1) && (nextHttp == -1) && (nextHttps == -1) && (nextSone == -1) && (nextPost == -1)) {
+ if (lineComplete && !lastLineEmpty) {
+ parts.add(new PlainTextPart("\n" + line));
+ } else {
+ parts.add(new PlainTextPart(line));
+ }
+ break;
+ }
+ int next = Integer.MAX_VALUE;
+ LinkType linkType = null;
+ if ((nextKsk > -1) && (nextKsk < next)) {
+ next = nextKsk;
+ linkType = LinkType.KSK;
+ }
+ if ((nextChk > -1) && (nextChk < next)) {
+ next = nextChk;
+ linkType = LinkType.CHK;
+ }
+ if ((nextSsk > -1) && (nextSsk < next)) {
+ next = nextSsk;
+ linkType = LinkType.SSK;
+ }
+ if ((nextUsk > -1) && (nextUsk < next)) {
+ next = nextUsk;
+ linkType = LinkType.USK;
+ }
+ if ((nextHttp > -1) && (nextHttp < next)) {
+ next = nextHttp;
+ linkType = LinkType.HTTP;
+ }
+ if ((nextHttps > -1) && (nextHttps < next)) {
+ next = nextHttps;
+ linkType = LinkType.HTTPS;
+ }
+ if ((nextSone > -1) && (nextSone < next)) {
+ next = nextSone;
+ linkType = LinkType.SONE;
+ }
+ if ((nextPost > -1) && (nextPost < next)) {
+ next = nextPost;
+ linkType = LinkType.POST;
}
- break;
- }
- int next = Integer.MAX_VALUE;
- LinkType linkType = null;
- if ((nextKsk > -1) && (nextKsk < next)) {
- next = nextKsk;
- linkType = LinkType.KSK;
- }
- if ((nextChk > -1) && (nextChk < next)) {
- next = nextChk;
- linkType = LinkType.CHK;
- }
- if ((nextSsk > -1) && (nextSsk < next)) {
- next = nextSsk;
- linkType = LinkType.SSK;
- }
- if ((nextUsk > -1) && (nextUsk < next)) {
- next = nextUsk;
- linkType = LinkType.USK;
- }
- if ((nextHttp > -1) && (nextHttp < next)) {
- next = nextHttp;
- linkType = LinkType.HTTP;
- }
- if ((nextHttps > -1) && (nextHttps < next)) {
- next = nextHttps;
- linkType = LinkType.HTTPS;
- }
- if ((nextSone > -1) && (nextSone < next)) {
- next = nextSone;
- linkType = LinkType.SONE;
- }
- if ((nextPost > -1) && (nextPost < next)) {
- next = nextPost;
- linkType = LinkType.POST;
- }
- /* cut off “freenet:” from before keys. */
- if (((linkType == LinkType.KSK) || (linkType == LinkType.CHK) || (linkType == LinkType.SSK) || (linkType == LinkType.USK)) && (next >= 8) && (line.substring(next - 8, next).equals("freenet:"))) {
- next -= 8;
- line = line.substring(0, next) + line.substring(next + 8);
- }
+ /* cut off “freenet:” from before keys. */
+ if (((linkType == LinkType.KSK) || (linkType == LinkType.CHK) || (linkType == LinkType.SSK) || (linkType == LinkType.USK)) && (next >= 8) && (line.substring(next - 8, next).equals("freenet:"))) {
+ next -= 8;
+ line = line.substring(0, next) + line.substring(next + 8);
+ }
- /* if there is text before the next item, write it out. */
- if (lineComplete && !lastLineEmpty) {
- parts.add(new PlainTextPart("\n"));
- }
- if (next > 0) {
- parts.add(new PlainTextPart(line.substring(0, next)));
- line = line.substring(next);
- next = 0;
- }
- lineComplete = false;
+ /* if there is text before the next item, write it out. */
+ if (lineComplete && !lastLineEmpty) {
+ parts.add(new PlainTextPart("\n"));
+ }
+ if (next > 0) {
+ parts.add(new PlainTextPart(line.substring(0, next)));
+ line = line.substring(next);
+ next = 0;
+ }
+ lineComplete = false;
- if (linkType == LinkType.SONE) {
- if (line.length() >= (7 + 43)) {
- String soneId = line.substring(7, 50);
- Sone sone = soneProvider.getSone(soneId, false);
- if (sone == null) {
- /*
- * don’t use create=true above, we don’t want the
- * empty shell.
- */
- sone = new MemorySone(soneId, false);
+ if (linkType == LinkType.SONE) {
+ if (line.length() >= (7 + 43)) {
+ String soneId = line.substring(7, 50);
+ Sone sone = soneProvider.getSone(soneId, false);
+ if (sone == null) {
+ /*
+ * don’t use create=true above, we don’t want
+ * the empty shell.
+ */
- sone = new Sone(soneId);
++ sone = new MemorySone(soneId, false);
+ }
+ parts.add(new SonePart(sone));
+ line = line.substring(50);
+ } else {
+ parts.add(new PlainTextPart(line));
+ line = "";
}
- parts.add(new SonePart(sone));
- line = line.substring(50);
- } else {
- parts.add(new PlainTextPart(line));
- line = "";
+ continue;
}
- continue;
- }
- if (linkType == LinkType.POST) {
- if (line.length() >= (7 + 36)) {
- String postId = line.substring(7, 43);
- Post post = postProvider.getPost(postId, false);
- if ((post != null) && (post.getSone() != null)) {
- parts.add(new PostPart(post));
+ if (linkType == LinkType.POST) {
+ if (line.length() >= (7 + 36)) {
+ String postId = line.substring(7, 43);
+ Post post = postProvider.getPost(postId, false);
+ if ((post != null) && (post.getSone() != null)) {
+ parts.add(new PostPart(post));
+ } else {
+ parts.add(new PlainTextPart(line.substring(0, 43)));
+ }
+ line = line.substring(43);
} else {
- parts.add(new PlainTextPart(line.substring(0, 43)));
+ parts.add(new PlainTextPart(line));
+ line = "";
}
- line = line.substring(43);
- } else {
- parts.add(new PlainTextPart(line));
- line = "";
+ continue;
}
- continue;
- }
- Matcher matcher = whitespacePattern.matcher(line);
- int nextSpace = matcher.find(0) ? matcher.start() : line.length();
- String link = line.substring(0, nextSpace);
- String name = link;
- logger.log(Level.FINER, String.format("Found link: %s", link));
- logger.log(Level.FINEST, String.format("CHK: %d, SSK: %d, USK: %d", nextChk, nextSsk, nextUsk));
+ Matcher matcher = whitespacePattern.matcher(line);
+ int nextSpace = matcher.find(0) ? matcher.start() : line.length();
+ String link = line.substring(0, nextSpace);
+ String name = link;
+ logger.log(Level.FINER, String.format("Found link: %s", link));
+ logger.log(Level.FINEST, String.format("CHK: %d, SSK: %d, USK: %d", nextChk, nextSsk, nextUsk));
- if ((linkType == LinkType.KSK) || (linkType == LinkType.CHK) || (linkType == LinkType.SSK) || (linkType == LinkType.USK)) {
- FreenetURI uri;
- if (name.indexOf('?') > -1) {
- name = name.substring(0, name.indexOf('?'));
- }
- if (name.endsWith("/")) {
- name = name.substring(0, name.length() - 1);
- }
- try {
- uri = new FreenetURI(name);
- name = uri.lastMetaString();
- if (name == null) {
- name = uri.getDocName();
+ if ((linkType == LinkType.KSK) || (linkType == LinkType.CHK) || (linkType == LinkType.SSK) || (linkType == LinkType.USK)) {
+ FreenetURI uri;
+ if (name.indexOf('?') > -1) {
+ name = name.substring(0, name.indexOf('?'));
}
- if (name == null) {
- name = link.substring(0, Math.min(9, link.length()));
+ if (name.endsWith("/")) {
+ name = name.substring(0, name.length() - 1);
}
- boolean fromPostingSone = ((linkType == LinkType.SSK) || (linkType == LinkType.USK)) && (context != null) && (context.getPostingSone() != null) && link.substring(4, Math.min(link.length(), 47)).equals(context.getPostingSone().getId());
- parts.add(new FreenetLinkPart(link, name, fromPostingSone));
- } catch (MalformedURLException mue1) {
- /* not a valid link, insert as plain text. */
- parts.add(new PlainTextPart(link));
- } catch (NullPointerException npe1) {
- /* FreenetURI sometimes throws these, too. */
- parts.add(new PlainTextPart(link));
- } catch (ArrayIndexOutOfBoundsException aioobe1) {
- /* oh, and these, too. */
- parts.add(new PlainTextPart(link));
- }
- } else if ((linkType == LinkType.HTTP) || (linkType == LinkType.HTTPS)) {
- name = link.substring(linkType == LinkType.HTTP ? 7 : 8);
- int firstSlash = name.indexOf('/');
- int lastSlash = name.lastIndexOf('/');
- if ((lastSlash - firstSlash) > 3) {
- name = name.substring(0, firstSlash + 1) + "…" + name.substring(lastSlash);
- }
- if (name.endsWith("/")) {
- name = name.substring(0, name.length() - 1);
- }
- if (((name.indexOf('/') > -1) && (name.indexOf('.') < name.lastIndexOf('.', name.indexOf('/'))) || ((name.indexOf('/') == -1) && (name.indexOf('.') < name.lastIndexOf('.')))) && name.startsWith("www.")) {
- name = name.substring(4);
- }
- if (name.indexOf('?') > -1) {
- name = name.substring(0, name.indexOf('?'));
+ try {
+ uri = new FreenetURI(name);
+ name = uri.lastMetaString();
+ if (name == null) {
+ name = uri.getDocName();
+ }
+ if (name == null) {
+ name = link.substring(0, Math.min(9, link.length()));
+ }
+ boolean fromPostingSone = ((linkType == LinkType.SSK) || (linkType == LinkType.USK)) && (context != null) && (context.getPostingSone() != null) && link.substring(4, Math.min(link.length(), 47)).equals(context.getPostingSone().getId());
+ parts.add(new FreenetLinkPart(link, name, fromPostingSone));
+ } catch (MalformedURLException mue1) {
+ /* not a valid link, insert as plain text. */
+ parts.add(new PlainTextPart(link));
+ } catch (NullPointerException npe1) {
+ /* FreenetURI sometimes throws these, too. */
+ parts.add(new PlainTextPart(link));
+ } catch (ArrayIndexOutOfBoundsException aioobe1) {
+ /* oh, and these, too. */
+ parts.add(new PlainTextPart(link));
+ }
+ } else if ((linkType == LinkType.HTTP) || (linkType == LinkType.HTTPS)) {
+ name = link.substring(linkType == LinkType.HTTP ? 7 : 8);
+ int firstSlash = name.indexOf('/');
+ int lastSlash = name.lastIndexOf('/');
+ if ((lastSlash - firstSlash) > 3) {
+ name = name.substring(0, firstSlash + 1) + "…" + name.substring(lastSlash);
+ }
+ if (name.endsWith("/")) {
+ name = name.substring(0, name.length() - 1);
+ }
+ if (((name.indexOf('/') > -1) && (name.indexOf('.') < name.lastIndexOf('.', name.indexOf('/'))) || ((name.indexOf('/') == -1) && (name.indexOf('.') < name.lastIndexOf('.')))) && name.startsWith("www.")) {
+ name = name.substring(4);
+ }
+ if (name.indexOf('?') > -1) {
+ name = name.substring(0, name.indexOf('?'));
+ }
+ parts.add(new LinkPart(link, name));
}
- parts.add(new LinkPart(link, name));
+ line = line.substring(nextSpace);
}
- line = line.substring(nextSpace);
+ lastLineEmpty = false;
+ }
+ } finally {
+ if (bufferedReader != source) {
+ Closer.close(bufferedReader);
}
- lastLineEmpty = false;
}
for (int partIndex = parts.size() - 1; partIndex >= 0; --partIndex) {
Part part = parts.getPart(partIndex);
throw new RedirectException("index.html");
}
- Set<Sone> sones = webInterface.getCore().getSones();
+ Collection<Sone> sones = webInterface.getCore().getSones();
Set<Hit<Sone>> soneHits = getHits(sones, phrases, SoneStringGenerator.COMPLETE_GENERATOR);
Set<Hit<Post>> postHits;
* The string generator for the objects
* @return The hits for the given phrases
*/
- private <T> Set<Hit<T>> getHits(Collection<T> objects, List<Phrase> phrases, StringGenerator<T> stringGenerator) {
+ private static <T> Set<Hit<T>> getHits(Collection<T> objects, List<Phrase> phrases, StringGenerator<T> stringGenerator) {
Set<Hit<T>> hits = new HashSet<Hit<T>>();
for (T object : objects) {
String objectString = stringGenerator.generateString(object);
* The query to parse
* @return The parsed phrases
*/
- private List<Phrase> parseSearchPhrases(String query) {
+ private static List<Phrase> parseSearchPhrases(String query) {
List<String> parsedPhrases = null;
try {
parsedPhrases = StringEscaper.parseLine(query);
* The expression to search
* @return The score of the expression
*/
- private double calculateScore(List<Phrase> phrases, String expression) {
+ private static double calculateScore(List<Phrase> phrases, String expression) {
logger.log(Level.FINEST, String.format("Calculating Score for “%s”…", expression));
double optionalHits = 0;
double requiredHits = 0;
import net.pterodactylus.util.template.HtmlFilter;
import net.pterodactylus.util.template.MatchFilter;
import net.pterodactylus.util.template.ModFilter;
+ import net.pterodactylus.util.template.PaginationFilter;
import net.pterodactylus.util.template.Provider;
import net.pterodactylus.util.template.ReflectionAccessor;
import net.pterodactylus.util.template.ReplaceFilter;
templateContextFactory.addFilter("in", new ContainsFilter());
templateContextFactory.addFilter("unique", new UniqueElementFilter());
templateContextFactory.addFilter("mod", new ModFilter());
+ templateContextFactory.addFilter("paginate", new PaginationFilter());
templateContextFactory.addProvider(Provider.TEMPLATE_CONTEXT_PROVIDER);
templateContextFactory.addProvider(new ClassPathTemplateProvider());
templateContextFactory.addTemplateObject("webInterface", this);
* currently logged in
*/
public Sone getCurrentSone(ToadletContext toadletContext, boolean create) {
- Set<Sone> localSones = getCore().getLocalSones();
+ Collection<Sone> localSones = getCore().getLocalSones();
if (localSones.size() == 1) {
return localSones.iterator().next();
}
}
/**
- * Returns all {@link Core#isLocalSone(Sone) local Sone}s that are
- * referenced by {@link SonePart}s in the given text (after parsing it using
+ * Returns all {@link Core#getLocalSones() local Sone}s that are referenced
+ * by {@link SonePart}s in the given text (after parsing it using
* {@link SoneTextParser}).
*
* @param text
*/
@Override
public void newPostFound(Post post) {
- boolean isLocal = getCore().isLocalSone(post.getSone());
- if (isLocal) {
+ if (post.getSone().isLocal()) {
localPostNotification.add(post);
} else {
newPostNotification.add(post);
}
if (!hasFirstStartNotification()) {
- notificationManager.addNotification(isLocal ? localPostNotification : newPostNotification);
- if (!getMentionedSones(post.getText()).isEmpty() && !isLocal) {
+ notificationManager.addNotification(post.getSone().isLocal() ? localPostNotification : newPostNotification);
+ if (!getMentionedSones(post.getText()).isEmpty() && !post.getSone().isLocal()) {
mentionNotification.add(post);
notificationManager.addNotification(mentionNotification);
}
*/
@Override
public void newReplyFound(PostReply reply) {
- boolean isLocal = getCore().isLocalSone(reply.getSone());
- if (isLocal) {
+ if (reply.getSone().isLocal()) {
localReplyNotification.add(reply);
} else {
newReplyNotification.add(reply);
}
if (!hasFirstStartNotification()) {
- notificationManager.addNotification(isLocal ? localReplyNotification : newReplyNotification);
- if (!getMentionedSones(reply.getText()).isEmpty() && !isLocal && (reply.getPost().getSone() != null) && (reply.getTime() <= System.currentTimeMillis())) {
+ notificationManager.addNotification(reply.getSone().isLocal() ? localReplyNotification : newReplyNotification);
+ if (!getMentionedSones(reply.getText()).isEmpty() && !reply.getSone().isLocal() && (reply.getPost().getSone() != null) && (reply.getTime() <= System.currentTimeMillis())) {
mentionNotification.add(reply.getPost());
notificationManager.addNotification(mentionNotification);
}
if (image == null) {
return createErrorJsonObject("invalid-image-id");
}
- if (!webInterface.getCore().isLocalSone(image.getSone())) {
+ if (!image.getSone().isLocal()) {
return createErrorJsonObject("not-authorized");
}
if ("true".equals(request.getHttpRequest().getParam("moveLeft"))) {
String description = request.getHttpRequest().getParam("description").trim();
image.setTitle(title).setDescription(TextFilter.filter(request.getHttpRequest().getHeader("host"), description));
webInterface.getCore().touchConfiguration();
- return createSuccessJsonObject().put("imageId", image.getId()).put("title", image.getTitle()).put("description", image.getDescription()).put("parsedDescription", (String) parserFilter.format(new TemplateContext(), image.getDescription(), new MapBuilder<String, String>().put("sone", image.getSone().getId()).get()));
+ return createSuccessJsonObject().put("imageId", image.getId()).put("title", image.getTitle()).put("description", image.getDescription()).put("parsedDescription", (String) parserFilter.format(new TemplateContext(), image.getDescription(), new MapBuilder<String, Object>().put("sone", image.getSone()).get()));
}
}
return createErrorJsonObject("invalid-" + type + "-id");
}
if ("post".equals(type)) {
- Post post = webInterface.getCore().getPost(id);
+ Post post = webInterface.getCore().getPost(id, false);
Set<Sone> sones = webInterface.getCore().getLikes(post);
return createSuccessJsonObject().put("likes", sones.size()).put("sones", getSones(sones));
} else if ("reply".equals(type)) {
* The Sones to convert to an array
* @return The Sones, sorted by name
*/
- private JsonArray getSones(Set<Sone> sones) {
+ private static JsonArray getSones(Set<Sone> sones) {
JsonArray soneArray = new JsonArray();
List<Sone> sortedSones = new ArrayList<Sone>(sones);
Collections.sort(sortedSones, Sone.NICE_NAME_COMPARATOR);