Blog Client with Factory and Validator

This implements a simple initial blog client that covers the basic blog
actions, but no deletion/removal of blogs, yet.

Classes for Blogs and Blog Post Headers have been introduced along with
the associated factories.

A `BlogPostValidator` has been added that validates incoming blog posts.

Closes #402
Closes #404
This commit is contained in:
Torsten Grote
2016-06-06 17:06:43 -03:00
parent bbed673150
commit da68ef78f1
21 changed files with 940 additions and 76 deletions

View File

@@ -0,0 +1,32 @@
package org.briarproject.api.blogs;
import org.briarproject.api.forum.Forum;
import org.briarproject.api.identity.Author;
import org.briarproject.api.sync.Group;
import org.jetbrains.annotations.NotNull;
public class Blog extends Forum {
@NotNull
private final String description;
@NotNull
private final Author author;
public Blog(@NotNull Group group, @NotNull String name,
@NotNull String description, @NotNull Author author) {
super(group, name, null);
this.description = description;
this.author = author;
}
@NotNull
public String getDescription() {
return description;
}
@NotNull
public Author getAuthor() {
return author;
}
}

View File

@@ -0,0 +1,39 @@
package org.briarproject.api.blogs;
import static org.briarproject.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
public interface BlogConstants {
/** The maximum length of a blogs's name in UTF-8 bytes. */
int MAX_BLOG_TITLE_LENGTH = 100;
/** The length of a blogs's description in UTF-8 bytes. */
int MAX_BLOG_DESC_LENGTH = 240;
/** The maximum length of a blog post's content type in UTF-8 bytes. */
int MAX_CONTENT_TYPE_LENGTH = 50;
/** The length of a blog post's title in UTF-8 bytes. */
int MAX_BLOG_POST_TITLE_LENGTH = 100;
/** The length of a blog post's teaser in UTF-8 bytes. */
int MAX_BLOG_POST_TEASER_LENGTH = 240;
/** The maximum length of a blog post's body in bytes. */
int MAX_BLOG_POST_BODY_LENGTH = MAX_MESSAGE_BODY_LENGTH - 1024;
// Metadata keys
String KEY_DESCRIPTION = "description";
String KEY_TITLE = "title";
String KEY_TEASER = "teaser";
String KEY_HAS_BODY = "hasBody";
String KEY_TIMESTAMP = "timestamp";
String KEY_PARENT = "parent";
String KEY_AUTHOR_ID = "id";
String KEY_AUTHOR_NAME = "name";
String KEY_PUBLIC_KEY = "publicKey";
String KEY_AUTHOR = "author";
String KEY_CONTENT_TYPE = "contentType";
String KEY_READ = "read";
}

View File

@@ -0,0 +1,17 @@
package org.briarproject.api.blogs;
import org.briarproject.api.FormatException;
import org.briarproject.api.identity.Author;
import org.briarproject.api.sync.Group;
import org.jetbrains.annotations.NotNull;
public interface BlogFactory {
/** Creates a blog with the given name, description and author. */
Blog createBlog(@NotNull String name, @NotNull String description,
@NotNull Author author);
/** Parses a blog with the given Group and description */
Blog parseBlog(@NotNull Group g, @NotNull String description)
throws FormatException;
}

View File

@@ -0,0 +1,48 @@
package org.briarproject.api.blogs;
import org.briarproject.api.FormatException;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
public interface BlogManager {
/** Returns the unique ID of the blog client. */
ClientId getClientId();
/** Creates a new Blog. */
Blog addBlog(LocalAuthor localAuthor, String name, String description)
throws DbException;
/** Stores a local blog post. */
void addLocalPost(BlogPost p) throws DbException;
/** Returns the blog with the given ID. */
Blog getBlog(GroupId g) throws DbException;
/** Returns the blog with the given ID. */
Blog getBlog(Transaction txn, GroupId g) throws DbException;
/** Returns all blogs to which the localAuthor created. */
Collection<Blog> getBlogs(LocalAuthor localAuthor) throws DbException;
/** Returns all blogs to which the user subscribes. */
Collection<Blog> getBlogs() throws DbException;
/** Returns the body of the blog post with the given ID. */
@Nullable
byte[] getPostBody(MessageId m) throws DbException;
/** Returns the headers of all posts in the given blog. */
Collection<BlogPostHeader> getPostHeaders(GroupId g) throws DbException;
/** Marks a blog post as read or unread. */
void setReadFlag(MessageId m, boolean read) throws DbException;
}

View File

@@ -0,0 +1,43 @@
package org.briarproject.api.blogs;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.briarproject.api.forum.ForumPost;
import org.briarproject.api.identity.Author;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
public class BlogPost extends ForumPost {
@Nullable
private final String title;
@NotNull
private final String teaser;
private final boolean hasBody;
public BlogPost(@Nullable String title, @NotNull String teaser,
boolean hasBody, @NotNull Message message,
@Nullable MessageId parent, @NotNull Author author,
@NotNull String contentType) {
super(message, parent, author, contentType);
this.title = title;
this.teaser = teaser;
this.hasBody = hasBody;
}
@Nullable
public String getTitle() {
return title;
}
@NotNull
public String getTeaser() {
return teaser;
}
public boolean hasBody() {
return hasBody;
}
}

View File

@@ -0,0 +1,19 @@
package org.briarproject.api.blogs;
import org.briarproject.api.FormatException;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.security.GeneralSecurityException;
public interface BlogPostFactory {
BlogPost createBlogPost(@NotNull GroupId groupId, @Nullable String title,
@NotNull String teaser, long timestamp, @Nullable MessageId parent,
@NotNull LocalAuthor author, @NotNull String contentType,
@Nullable byte[] body)
throws FormatException, GeneralSecurityException;
}

View File

@@ -0,0 +1,43 @@
package org.briarproject.api.blogs;
import org.briarproject.api.clients.PostHeader;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.Author.Status;
import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class BlogPostHeader extends PostHeader {
@Nullable
private final String title;
@NotNull
private final String teaser;
private final boolean hasBody;
public BlogPostHeader(@Nullable String title, @NotNull String teaser,
boolean hasBody, @NotNull MessageId id,
@Nullable MessageId parentId, long timestamp,
@NotNull Author author, @NotNull Status authorStatus,
@NotNull String contentType, boolean read) {
super(id, parentId, timestamp, author, authorStatus, contentType, read);
this.title = title;
this.teaser = teaser;
this.hasBody = hasBody;
}
@Nullable
public String getTitle() {
return title;
}
@NotNull
public String getTeaser() {
return teaser;
}
public boolean hasBody() {
return hasBody;
}
}