import java.util.List;
import java.util.UUID;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
* @param profile
* The profile to copy
*/
- public Profile(Profile profile) {
+ public Profile(@Nonnull Profile profile) {
this.sone = profile.sone;
this.firstName = profile.firstName;
this.middleName = profile.middleName;
*
* @return The Sone this profile belongs to
*/
+ @Nonnull
public Sone getSone() {
return sone;
}
*
* @return The first name
*/
+ @Nullable
public String getFirstName() {
return firstName;
}
* The first name to set
* @return This profile (for method chaining)
*/
- public Profile setFirstName(String firstName) {
+ @Nonnull
+ public Profile setFirstName(@Nullable String firstName) {
this.firstName = firstName;
return this;
}
*
* @return The middle name
*/
+ @Nullable
public String getMiddleName() {
return middleName;
}
* The middle name to set
* @return This profile (for method chaining)
*/
- public Profile setMiddleName(String middleName) {
+ @Nonnull
+ public Profile setMiddleName(@Nullable String middleName) {
this.middleName = middleName;
return this;
}
*
* @return The last name
*/
+ @Nullable
public String getLastName() {
return lastName;
}
* The last name to set
* @return This profile (for method chaining)
*/
- public Profile setLastName(String lastName) {
+ @Nonnull
+ public Profile setLastName(@Nullable String lastName) {
this.lastName = lastName;
return this;
}
*
* @return The day of the birth date (from 1 to 31)
*/
+ @Nullable
public Integer getBirthDay() {
return birthDay;
}
* The day of the birth date (from 1 to 31)
* @return This profile (for method chaining)
*/
- public Profile setBirthDay(Integer birthDay) {
+ @Nonnull
+ public Profile setBirthDay(@Nullable Integer birthDay) {
this.birthDay = birthDay;
return this;
}
*
* @return The month of the birth date (from 1 to 12)
*/
+ @Nullable
public Integer getBirthMonth() {
return birthMonth;
}
* The month of the birth date (from 1 to 12)
* @return This profile (for method chaining)
*/
- public Profile setBirthMonth(Integer birthMonth) {
+ @Nonnull
+ public Profile setBirthMonth(@Nullable Integer birthMonth) {
this.birthMonth = birthMonth;
return this;
}
*
* @return The year of the birth date
*/
+ @Nullable
public Integer getBirthYear() {
return birthYear;
}
* @return The ID of the currently selected avatar image, or {@code null} if
* no avatar is selected.
*/
+ @Nullable
public String getAvatar() {
return avatar;
}
* image.
* @return This Sone
*/
- public Profile setAvatar(Image avatar) {
+ @Nonnull
+ public Profile setAvatar(@Nullable Image avatar) {
if (avatar == null) {
this.avatar = null;
return this;
* The year of the birth date
* @return This profile (for method chaining)
*/
- public Profile setBirthYear(Integer birthYear) {
+ @Nonnull
+ public Profile setBirthYear(@Nullable Integer birthYear) {
this.birthYear = birthYear;
return this;
}
*
* @return The fields of this profile
*/
+ @Nonnull
public List<Field> getFields() {
return new ArrayList<Field>(fields);
}
* The field to check for
* @return {@code true} if this profile contains the field, false otherwise
*/
- public boolean hasField(Field field) {
+ public boolean hasField(@Nonnull Field field) {
return fields.contains(field);
}
* @return The field, or {@code null} if this profile does not contain a
* field with the given ID
*/
- public Field getFieldById(String fieldId) {
+ @Nullable
+ public Field getFieldById(@Nonnull String fieldId) {
checkNotNull(fieldId, "fieldId must not be null");
for (Field field : fields) {
if (field.getId().equals(fieldId)) {
* @return The field, or {@code null} if this profile does not contain a
* field with the given name
*/
- public Field getFieldByName(String fieldName) {
+ @Nullable
+ public Field getFieldByName(@Nonnull String fieldName) {
for (Field field : fields) {
if (field.getName().equals(fieldName)) {
return field;
* @throws IllegalArgumentException
* if the name is not valid
*/
- public Field addField(String fieldName) throws IllegalArgumentException {
+ @Nonnull
+ public Field addField(@Nonnull String fieldName) throws IllegalArgumentException {
checkNotNull(fieldName, "fieldName must not be null");
if (fieldName.length() == 0) {
throw new EmptyFieldName();
* @param field
* The field to move up
*/
- public void moveFieldUp(Field field) {
+ public void moveFieldUp(@Nonnull Field field) {
checkNotNull(field, "field must not be null");
checkArgument(hasField(field), "field must belong to this profile");
checkArgument(getFieldIndex(field) > 0, "field index must be > 0");
* @param field
* The field to move down
*/
- public void moveFieldDown(Field field) {
+ public void moveFieldDown(@Nonnull Field field) {
checkNotNull(field, "field must not be null");
checkArgument(hasField(field), "field must belong to this profile");
checkArgument(getFieldIndex(field) < fields.size() - 1, "field index must be < " + (fields.size() - 1));
* @param field
* The field to remove
*/
- public void removeField(Field field) {
+ public void removeField(@Nonnull Field field) {
checkNotNull(field, "field must not be null");
checkArgument(hasField(field), "field must belong to this profile");
fields.remove(field);
* @return The index of the field, or {@code -1} if there is no field with
* the given name
*/
- private int getFieldIndex(Field field) {
+ private int getFieldIndex(@Nonnull Field field) {
return fields.indexOf(field);
}
* @param id
* The ID of the field
*/
- private Field(String id) {
+ private Field(@Nonnull String id) {
this.id = checkNotNull(id, "id must not be null");
}
*
* @return The ID of this field
*/
+ @Nonnull
public String getId() {
return id;
}
*
* @return The name of this field
*/
+ @Nonnull
public String getName() {
return name;
}
* The new name of this field
* @return This field
*/
- public Field setName(String name) {
+ @Nonnull
+ public Field setName(@Nonnull String name) {
checkNotNull(name, "name must not be null");
checkArgument(getFieldByName(name) == null, "name must be unique");
this.name = name;
*
* @return The value of this field
*/
+ @Nullable
public String getValue() {
return value;
}
* The new value of this field
* @return This field
*/
- public Field setValue(String value) {
+ @Nonnull
+ public Field setValue(@Nullable String value) {
this.value = value;
return this;
}
*
* @return The identity of this Sone
*/
+ @Nonnull
Identity getIdentity();
/**
*
* @return The name of this Sone
*/
+ @Nonnull
String getName();
/**
*
* @return The request URI of this Sone
*/
+ @Nonnull
FreenetURI getRequestUri();
/**
*
* @return The insert URI of this Sone
*/
+ @Nullable
FreenetURI getInsertUri();
/**
* The time of the update (in milliseconds since Jan 1, 1970 UTC)
* @return This Sone (for method chaining)
*/
+ @Nonnull
Sone setTime(long time);
/**
*
* @return The status of this Sone
*/
+ @Nonnull
SoneStatus getStatus();
/**
* @throws IllegalArgumentException
* if {@code status} is {@code null}
*/
- Sone setStatus(SoneStatus status);
+ @Nonnull
+ Sone setStatus(@Nonnull SoneStatus status);
/**
* Returns a copy of the profile. If you want to update values in the profile
*
* @return A copy of the profile
*/
+ @Nonnull
Profile getProfile();
/**
* @param profile
* The profile to set
*/
- void setProfile(Profile profile);
+ void setProfile(@Nonnull Profile profile);
/**
* Returns the client used by this Sone.
*
* @return The client used by this Sone, or {@code null}
*/
+ @Nullable
Client getClient();
/**
* The client used by this Sone, or {@code null}
* @return This Sone (for method chaining)
*/
- Sone setClient(Client client);
+ @Nonnull
+ Sone setClient(@Nullable Client client);
/**
* Returns whether this Sone is known.
* {@code true} if this Sone is known, {@code false} otherwise
* @return This Sone
*/
+ @Nonnull
Sone setKnown(boolean known);
/**
*
* @return The friend Sones of this Sone
*/
+ @Nonnull
Collection<String> getFriends();
/**
* @return {@code true} if this Sone has the given Sone as a friend, {@code
* false} otherwise
*/
- boolean hasFriend(String friendSoneId);
+ boolean hasFriend(@Nonnull String friendSoneId);
/**
* Returns the list of posts of this Sone, sorted by time, newest first.
*
* @return All posts of this Sone
*/
+ @Nonnull
List<Post> getPosts();
/**
* The new (and only) posts of this Sone
* @return This Sone (for method chaining)
*/
- Sone setPosts(Collection<Post> posts);
+ @Nonnull
+ Sone setPosts(@Nonnull Collection<Post> posts);
/**
* Adds the given post to this Sone. The post will not be added if its {@link
* @param post
* The post to add
*/
- void addPost(Post post);
+ void addPost(@Nonnull Post post);
/**
* Removes the given post from this Sone.
* @param post
* The post to remove
*/
- void removePost(Post post);
+ void removePost(@Nonnull Post post);
/**
* Returns all replies this Sone made.
*
* @return All replies this Sone made
*/
+ @Nonnull
Set<PostReply> getReplies();
/**
* The new (and only) replies of this Sone
* @return This Sone (for method chaining)
*/
- Sone setReplies(Collection<PostReply> replies);
+ @Nonnull
+ Sone setReplies(@Nonnull Collection<PostReply> replies);
/**
* Adds a reply to this Sone. If the given reply was not made by this Sone,
* @param reply
* The reply to add
*/
- void addReply(PostReply reply);
+ void addReply(@Nonnull PostReply reply);
/**
* Removes a reply from this Sone.
* @param reply
* The reply to remove
*/
- void removeReply(PostReply reply);
+ void removeReply(@Nonnull PostReply reply);
/**
* Returns the IDs of all liked posts.
*
* @return All liked posts’ IDs
*/
+ @Nonnull
Set<String> getLikedPostIds();
/**
* All liked posts’ IDs
* @return This Sone (for method chaining)
*/
- Sone setLikePostIds(Set<String> likedPostIds);
+ @Nonnull
+ Sone setLikePostIds(@Nonnull Set<String> likedPostIds);
/**
* Checks whether the given post ID is liked by this Sone.
* @return {@code true} if this Sone likes the given post, {@code false}
* otherwise
*/
- boolean isLikedPostId(String postId);
+ boolean isLikedPostId(@Nonnull String postId);
/**
* Adds the given post ID to the list of posts this Sone likes.
* The ID of the post
* @return This Sone (for method chaining)
*/
- Sone addLikedPostId(String postId);
+ @Nonnull
+ Sone addLikedPostId(@Nonnull String postId);
/**
* Removes the given post ID from the list of posts this Sone likes.
* The ID of the post
* @return This Sone (for method chaining)
*/
- Sone removeLikedPostId(String postId);
+ @Nonnull
+ Sone removeLikedPostId(@Nonnull String postId);
/**
* Returns the IDs of all liked replies.
*
* @return All liked replies’ IDs
*/
+ @Nonnull
Set<String> getLikedReplyIds();
/**
* All liked replies’ IDs
* @return This Sone (for method chaining)
*/
- Sone setLikeReplyIds(Set<String> likedReplyIds);
+ @Nonnull
+ Sone setLikeReplyIds(@Nonnull Set<String> likedReplyIds);
/**
* Checks whether the given reply ID is liked by this Sone.
* @return {@code true} if this Sone likes the given reply, {@code false}
* otherwise
*/
- boolean isLikedReplyId(String replyId);
+ boolean isLikedReplyId(@Nonnull String replyId);
/**
* Adds the given reply ID to the list of replies this Sone likes.
* The ID of the reply
* @return This Sone (for method chaining)
*/
- Sone addLikedReplyId(String replyId);
+ @Nonnull
+ Sone addLikedReplyId(@Nonnull String replyId);
/**
* Removes the given post ID from the list of replies this Sone likes.
* The ID of the reply
* @return This Sone (for method chaining)
*/
- Sone removeLikedReplyId(String replyId);
+ @Nonnull
+ Sone removeLikedReplyId(@Nonnull String replyId);
/**
* Returns the root album that contains all visible albums of this Sone.
*
* @return The root album of this Sone
*/
+ @Nonnull
Album getRootAlbum();
/**
*
* @return The options of this Sone
*/
+ @Nonnull
SoneOptions getOptions();
/**
* The options of this Sone
*/
/* TODO - remove this method again, maybe add an option provider */
- void setOptions(SoneOptions options);
+ void setOptions(@Nonnull SoneOptions options);
}
import java.util.logging.Level;
import java.util.logging.Logger;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
import net.pterodactylus.sone.data.Album;
import net.pterodactylus.sone.data.Client;
import net.pterodactylus.sone.data.Post;
*
* @return The identity of this Sone
*/
+ @Nonnull
public String getId() {
return id;
}
*
* @return The identity of this Sone
*/
+ @Nonnull
public Identity getIdentity() {
return identity;
}
*
* @return The name of this Sone
*/
+ @Nonnull
public String getName() {
return (identity != null) ? identity.getNickname() : null;
}
*
* @return The request URI of this Sone
*/
+ @Nonnull
public FreenetURI getRequestUri() {
try {
return new FreenetURI(getIdentity().getRequestUri())
*
* @return The insert URI of this Sone
*/
+ @Nullable
public FreenetURI getInsertUri() {
if (!isLocal()) {
return null;
* The time of the update (in milliseconds since Jan 1, 1970 UTC)
* @return This Sone (for method chaining)
*/
+ @Nonnull
public Sone setTime(long time) {
this.time = time;
return this;
*
* @return The status of this Sone
*/
+ @Nonnull
public SoneStatus getStatus() {
return status;
}
* @throws IllegalArgumentException
* if {@code status} is {@code null}
*/
- public Sone setStatus(SoneStatus status) {
+ @Nonnull
+ public Sone setStatus(@Nonnull SoneStatus status) {
this.status = checkNotNull(status, "status must not be null");
return this;
}
*
* @return A copy of the profile
*/
+ @Nonnull
public Profile getProfile() {
return new Profile(profile);
}
* @param profile
* The profile to set
*/
- public void setProfile(Profile profile) {
+ public void setProfile(@Nonnull Profile profile) {
this.profile = new Profile(profile);
}
*
* @return The client used by this Sone, or {@code null}
*/
+ @Nullable
public Client getClient() {
return client;
}
* The client used by this Sone, or {@code null}
* @return This Sone (for method chaining)
*/
- public Sone setClient(Client client) {
+ @Nonnull
+ public Sone setClient(@Nullable Client client) {
this.client = client;
return this;
}
* {@code true} if this Sone is known, {@code false} otherwise
* @return This Sone
*/
+ @Nonnull
public Sone setKnown(boolean known) {
this.known = known;
return this;
*
* @return The friend Sones of this Sone
*/
+ @Nonnull
public Collection<String> getFriends() {
return database.getFriends(this);
}
* @return {@code true} if this Sone has the given Sone as a friend, {@code
* false} otherwise
*/
- public boolean hasFriend(String friendSoneId) {
+ public boolean hasFriend(@Nonnull String friendSoneId) {
return database.isFriend(this, friendSoneId);
}
*
* @return All posts of this Sone
*/
+ @Nonnull
public List<Post> getPosts() {
List<Post> sortedPosts;
synchronized (this) {
* The new (and only) posts of this Sone
* @return This Sone (for method chaining)
*/
- public Sone setPosts(Collection<Post> posts) {
+ @Nonnull
+ public Sone setPosts(@Nonnull Collection<Post> posts) {
synchronized (this) {
this.posts.clear();
this.posts.addAll(posts);
* @param post
* The post to add
*/
- public void addPost(Post post) {
+ public void addPost(@Nonnull Post post) {
if (post.getSone().equals(this) && posts.add(post)) {
logger.log(Level.FINEST, String.format("Adding %s to “%s”.", post, getName()));
}
* @param post
* The post to remove
*/
- public void removePost(Post post) {
+ public void removePost(@Nonnull Post post) {
if (post.getSone().equals(this)) {
posts.remove(post);
}
*
* @return All replies this Sone made
*/
+ @Nonnull
public Set<PostReply> getReplies() {
return Collections.unmodifiableSet(replies);
}
* The new (and only) replies of this Sone
* @return This Sone (for method chaining)
*/
- public Sone setReplies(Collection<PostReply> replies) {
+ @Nonnull
+ public Sone setReplies(@Nonnull Collection<PostReply> replies) {
this.replies.clear();
this.replies.addAll(replies);
return this;
* @param reply
* The reply to add
*/
- public void addReply(PostReply reply) {
+ public void addReply(@Nonnull PostReply reply) {
if (reply.getSone().equals(this)) {
replies.add(reply);
}
* @param reply
* The reply to remove
*/
- public void removeReply(PostReply reply) {
+ public void removeReply(@Nonnull PostReply reply) {
if (reply.getSone().equals(this)) {
replies.remove(reply);
}
*
* @return All liked posts’ IDs
*/
+ @Nonnull
public Set<String> getLikedPostIds() {
return Collections.unmodifiableSet(likedPostIds);
}
* All liked posts’ IDs
* @return This Sone (for method chaining)
*/
- public Sone setLikePostIds(Set<String> likedPostIds) {
+ @Nonnull
+ public Sone setLikePostIds(@Nonnull Set<String> likedPostIds) {
this.likedPostIds.clear();
this.likedPostIds.addAll(likedPostIds);
return this;
* @return {@code true} if this Sone likes the given post, {@code false}
* otherwise
*/
- public boolean isLikedPostId(String postId) {
+ public boolean isLikedPostId(@Nonnull String postId) {
return likedPostIds.contains(postId);
}
* The ID of the post
* @return This Sone (for method chaining)
*/
- public Sone addLikedPostId(String postId) {
+ @Nonnull
+ public Sone addLikedPostId(@Nonnull String postId) {
likedPostIds.add(postId);
return this;
}
* The ID of the post
* @return This Sone (for method chaining)
*/
- public Sone removeLikedPostId(String postId) {
+ @Nonnull
+ public Sone removeLikedPostId(@Nonnull String postId) {
likedPostIds.remove(postId);
return this;
}
*
* @return All liked replies’ IDs
*/
+ @Nonnull
public Set<String> getLikedReplyIds() {
return Collections.unmodifiableSet(likedReplyIds);
}
* All liked replies’ IDs
* @return This Sone (for method chaining)
*/
- public Sone setLikeReplyIds(Set<String> likedReplyIds) {
+ @Nonnull
+ public Sone setLikeReplyIds(@Nonnull Set<String> likedReplyIds) {
this.likedReplyIds.clear();
this.likedReplyIds.addAll(likedReplyIds);
return this;
* @return {@code true} if this Sone likes the given reply, {@code false}
* otherwise
*/
- public boolean isLikedReplyId(String replyId) {
+ public boolean isLikedReplyId(@Nonnull String replyId) {
return likedReplyIds.contains(replyId);
}
* The ID of the reply
* @return This Sone (for method chaining)
*/
- public Sone addLikedReplyId(String replyId) {
+ @Nonnull
+ public Sone addLikedReplyId(@Nonnull String replyId) {
likedReplyIds.add(replyId);
return this;
}
* The ID of the reply
* @return This Sone (for method chaining)
*/
- public Sone removeLikedReplyId(String replyId) {
+ @Nonnull
+ public Sone removeLikedReplyId(@Nonnull String replyId) {
likedReplyIds.remove(replyId);
return this;
}
*
* @return The root album of this Sone
*/
+ @Nonnull
public Album getRootAlbum() {
return rootAlbum;
}
*
* @return The options of this Sone
*/
+ @Nonnull
public SoneOptions getOptions() {
return options;
}
* The options of this Sone
*/
/* TODO - remove this method again, maybe add an option provider */
- public void setOptions(SoneOptions options) {
+ public void setOptions(@Nonnull SoneOptions options) {
this.options = options;
}
inline fun <reified T : Any> bindMock(): Module =
Module { it!!.bind(T::class.java).toInstance(mock<T>()) }
-inline fun <reified T: Any> whenever(methodCall: T) = Mockito.`when`(methodCall)
+inline fun <reified T: Any?> whenever(methodCall: T) = Mockito.`when`(methodCall)!!
inline fun <reified T : Any> OngoingStubbing<T>.thenReturnMock(): OngoingStubbing<T> = this.thenReturn(mock<T>())
fun `post request with field value saves profile and redirects back to profile edit page`() {
val field = profile.addField("name")
field.value = "old"
- verifySingleFieldCanBeChanged("field-${field.id}", "new") { profile.getFieldByName("name").value }
+ verifySingleFieldCanBeChanged("field-${field.id}", "new") { profile.getFieldByName("name")!!.value }
}
@Test
val field = profile.addField("name")
field.value = "old"
addHttpRequestHeader("Host", "www.te.st")
- verifySingleFieldCanBeChanged("field-${field.id}", "http://www.te.st/KSK@GPL.txt", "KSK@GPL.txt") { profile.getFieldByName("name").value }
+ verifySingleFieldCanBeChanged("field-${field.id}", "http://www.te.st/KSK@GPL.txt", "KSK@GPL.txt") { profile.getFieldByName("name")!!.value }
}
@Test