org.entcore.blog.services.impl.DefaultPostService.java Source code

Java tutorial

Introduction

Here is the source code for org.entcore.blog.services.impl.DefaultPostService.java

Source

/*
 * Copyright  "Open Digital Education" (SAS WebServices pour lEducation?), 2014
 *
 * This program is published by "Open Digital Education" (SAS WebServices pour lEducation?).
 * You must indicate the name of the software and the company in any production /contribution
 * using the software and indicate on the home page of the software industry in question,
 * "powered by Open Digital Education" with a reference to the website: https: //opendigitaleducation.com/.
 *
 * This program is free software, licensed under the terms of the GNU Affero General Public License
 * as published by the Free Software Foundation, version 3 of the License.
 *
 * You can redistribute this application and/or modify it since you respect the terms of the GNU Affero General Public License.
 * If you modify the source code and then use this modified source code in your creation, you must make available the source code of your modifications.
 *
 * You should have received a copy of the GNU Affero General Public License along with the software.
 * If not, please see : <http://www.gnu.org/licenses/>. Full compliance requires reading the terms of this license and following its directives.
 *
 * 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.
 */

package org.entcore.blog.services.impl;

import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import fr.wseduc.mongodb.MongoDb;
import fr.wseduc.mongodb.MongoQueryBuilder;
import fr.wseduc.mongodb.MongoUpdateBuilder;
import org.entcore.blog.services.BlogService;
import org.entcore.blog.services.PostService;
import fr.wseduc.webutils.*;

import org.entcore.common.mongodb.MongoDbResult;
import org.entcore.common.service.impl.MongoDbSearchService;
import org.entcore.common.user.UserInfos;
import org.entcore.common.utils.StringUtils;
import io.vertx.core.Handler;
import io.vertx.core.eventbus.Message;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

import java.util.*;

public class DefaultPostService implements PostService {
    private final String listPostAction;
    private final MongoDb mongo;
    protected static final String POST_COLLECTION = "posts";
    private static final JsonObject defaultKeys = new JsonObject().put("author", 1).put("title", 1)
            .put("content", 1).put("state", 1).put("created", 1).put("modified", 1).put("views", 1)
            .put("firstPublishDate", 1);

    private int searchWordMinSize;

    public DefaultPostService(MongoDb mongo, int searchWordMinSize, String listPostAction) {
        this.mongo = mongo;
        this.listPostAction = listPostAction;
        this.searchWordMinSize = searchWordMinSize;
    }

    @Override
    public void create(String blogId, JsonObject post, UserInfos author,
            final Handler<Either<String, JsonObject>> result) {
        JsonObject now = MongoDb.now();
        JsonObject blogRef = new JsonObject().put("$ref", "blogs").put("$id", blogId);
        JsonObject owner = new JsonObject().put("userId", author.getUserId()).put("username", author.getUsername())
                .put("login", author.getLogin());
        post.put("created", now).put("modified", now).put("author", owner).put("state", StateType.DRAFT.name())
                .put("comments", new JsonArray()).put("views", 0).put("blog", blogRef);
        JsonObject b = Utils.validAndGet(post, FIELDS, FIELDS);
        if (validationError(result, b))
            return;
        b.put("sorted", now);
        if (b.containsKey("content")) {
            b.put("contentPlain", StringUtils.stripHtmlTag(b.getString("content", "")));
        }
        mongo.save(POST_COLLECTION, b,
                MongoDbResult.validActionResultHandler(new Handler<Either<String, JsonObject>>() {
                    public void handle(Either<String, JsonObject> event) {
                        if (event.isLeft()) {
                            result.handle(event);
                            return;
                        }
                        mongo.findOne(POST_COLLECTION,
                                new JsonObject().put("_id", event.right().getValue().getString("_id")),
                                MongoDbResult.validResultHandler(result));
                    }
                }));
    }

    @Override
    public void update(String postId, final JsonObject post, final UserInfos user,
            final Handler<Either<String, JsonObject>> result) {

        final JsonObject jQuery = MongoQueryBuilder.build(QueryBuilder.start("_id").is(postId));
        mongo.findOne(POST_COLLECTION, jQuery,
                MongoDbResult.validActionResultHandler(new Handler<Either<String, JsonObject>>() {
                    public void handle(Either<String, JsonObject> event) {
                        if (event.isLeft()) {
                            result.handle(event);
                            return;
                        } else {
                            final JsonObject postFromDb = event.right().getValue().getJsonObject("result",
                                    new JsonObject());
                            final JsonObject now = MongoDb.now();
                            post.put("modified", now);
                            final JsonObject b = Utils.validAndGet(post, UPDATABLE_FIELDS,
                                    Collections.<String>emptyList());

                            if (validationError(result, b))
                                return;
                            if (b.containsKey("content")) {
                                b.put("contentPlain", StringUtils.stripHtmlTag(b.getString("content", "")));
                            }

                            if (postFromDb.getJsonObject("firstPublishDate") != null) {
                                b.put("sorted", postFromDb.getJsonObject("firstPublishDate"));
                            } else {
                                b.put("sorted", now);
                            }

                            //if user is author, draft state
                            if (user.getUserId().equals(
                                    postFromDb.getJsonObject("author", new JsonObject()).getString("userId"))) {
                                b.put("state", StateType.DRAFT.name());
                            }

                            MongoUpdateBuilder modifier = new MongoUpdateBuilder();
                            for (String attr : b.fieldNames()) {
                                modifier.set(attr, b.getValue(attr));
                            }
                            mongo.update(POST_COLLECTION, jQuery, modifier.build(),
                                    new Handler<Message<JsonObject>>() {
                                        @Override
                                        public void handle(Message<JsonObject> event) {
                                            if ("ok".equals(event.body().getString("status"))) {
                                                final JsonObject r = new JsonObject().put("state",
                                                        b.getString("state", postFromDb.getString("state")));
                                                result.handle(new Either.Right<String, JsonObject>(r));
                                            } else {
                                                result.handle(new Either.Left<String, JsonObject>(
                                                        event.body().getString("message", "")));
                                            }
                                        }
                                    });
                        }
                    }
                }));

    }

    @Override
    public void delete(String postId, final Handler<Either<String, JsonObject>> result) {
        QueryBuilder query = QueryBuilder.start("_id").is(postId);
        mongo.delete(POST_COLLECTION, MongoQueryBuilder.build(query), new Handler<Message<JsonObject>>() {
            @Override
            public void handle(Message<JsonObject> event) {
                result.handle(Utils.validResult(event));
            }
        });
    }

    @Override
    public void get(String blogId, final String postId, StateType state,
            final Handler<Either<String, JsonObject>> result) {
        QueryBuilder query = QueryBuilder.start("_id").is(postId).put("blog.$id").is(blogId).put("state")
                .is(state.name());

        mongo.findOne(POST_COLLECTION, MongoQueryBuilder.build(query), defaultKeys,
                new Handler<Message<JsonObject>>() {
                    @Override
                    public void handle(Message<JsonObject> event) {
                        Either<String, JsonObject> res = Utils.validResult(event);
                        if (res.isRight() && res.right().getValue().size() > 0) {
                            QueryBuilder query2 = QueryBuilder.start("_id").is(postId).put("state")
                                    .is(StateType.PUBLISHED.name());
                            MongoUpdateBuilder incView = new MongoUpdateBuilder();
                            incView.inc("views", 1);
                            mongo.update(POST_COLLECTION, MongoQueryBuilder.build(query2), incView.build());
                        }
                        result.handle(res);
                    }
                });
    }

    @Override
    public void list(String blogId, final UserInfos user, final Integer page, final int limit, final String search,
            final Set<String> states, final Handler<Either<String, JsonArray>> result) {
        final QueryBuilder accessQuery;
        if (states == null || states.isEmpty()) {
            accessQuery = QueryBuilder.start("blog.$id").is(blogId);
        } else {
            accessQuery = QueryBuilder.start("blog.$id").is(blogId).put("state").in(states);
        }

        final QueryBuilder isManagerQuery = getDefautQueryBuilderForList(blogId, user, true);
        final JsonObject sort = new JsonObject().put("modified", -1);
        final JsonObject projection = defaultKeys.copy();
        projection.remove("content");

        final Handler<Message<JsonObject>> finalHandler = new Handler<Message<JsonObject>>() {
            @Override
            public void handle(Message<JsonObject> event) {
                result.handle(Utils.validResults(event));
            }
        };

        mongo.count("blogs", MongoQueryBuilder.build(isManagerQuery), new Handler<Message<JsonObject>>() {
            public void handle(Message<JsonObject> event) {
                JsonObject res = event.body();
                if (res == null || !"ok".equals(res.getString("status"))) {
                    result.handle(new Either.Left<String, JsonArray>(event.body().encodePrettily()));
                    return;
                }
                boolean isManager = 1 == res.getInteger("count", 0);

                accessQuery.or(QueryBuilder.start("state").is(StateType.PUBLISHED.name()).get(),
                        QueryBuilder.start()
                                .and(QueryBuilder.start("author.userId").is(user.getUserId()).get(),
                                        QueryBuilder.start("state").is(StateType.DRAFT.name()).get())
                                .get(),
                        isManager ? QueryBuilder.start("state").is(StateType.SUBMITTED.name()).get()
                                : QueryBuilder.start()
                                        .and(QueryBuilder.start("author.userId").is(user.getUserId()).get(),
                                                QueryBuilder.start("state").is(StateType.SUBMITTED.name()).get())
                                        .get());

                final QueryBuilder query = getQueryListBuilder(search, result, accessQuery);

                if (query != null) {
                    if (limit > 0 && page == null) {
                        mongo.find(POST_COLLECTION, MongoQueryBuilder.build(query), sort, projection, 0, limit,
                                limit, finalHandler);
                    } else if (page == null) {
                        mongo.find(POST_COLLECTION, MongoQueryBuilder.build(query), sort, projection, finalHandler);
                    } else {
                        final JsonObject sortPag = new JsonObject().put("sorted", -1);
                        final int skip = (0 == page) ? -1 : page * limit;
                        mongo.find(POST_COLLECTION, MongoQueryBuilder.build(query), sortPag, projection, skip,
                                limit, limit, finalHandler);
                    }
                }
            }
        });
    }

    @Override
    public void counter(final String blogId, final UserInfos user,
            final Handler<Either<String, JsonArray>> result) {
        final QueryBuilder query = QueryBuilder.start("blog.$id").is(blogId);
        final QueryBuilder isManagerQuery = getDefautQueryBuilderForList(blogId, user, true);
        final JsonObject projection = new JsonObject();
        projection.put("state", 1);
        projection.put("_id", -1);

        final Handler<Message<JsonObject>> finalHandler = new Handler<Message<JsonObject>>() {
            @Override
            public void handle(Message<JsonObject> event) {
                result.handle(Utils.validResults(event));
            }
        };

        mongo.count("blogs", MongoQueryBuilder.build(isManagerQuery), new Handler<Message<JsonObject>>() {
            public void handle(Message<JsonObject> event) {
                JsonObject res = event.body();
                if (res == null || !"ok".equals(res.getString("status"))) {
                    result.handle(new Either.Left<String, JsonArray>(event.body().encodePrettily()));
                    return;
                }
                boolean isManager = 1 == res.getInteger("count", 0);

                query.or(QueryBuilder.start("state").is(StateType.PUBLISHED.name()).get(),
                        QueryBuilder.start()
                                .and(QueryBuilder.start("author.userId").is(user.getUserId()).get(),
                                        QueryBuilder.start("state").is(StateType.DRAFT.name()).get())
                                .get(),
                        isManager ? QueryBuilder.start("state").is(StateType.SUBMITTED.name()).get()
                                : QueryBuilder.start()
                                        .and(QueryBuilder.start("author.userId").is(user.getUserId()).get(),
                                                QueryBuilder.start("state").is(StateType.SUBMITTED.name()).get())
                                        .get());
                mongo.find(POST_COLLECTION, MongoQueryBuilder.build(query), null, projection, finalHandler);
            }
        });
    }

    @Override
    public void list(String blogId, final StateType state, final UserInfos user, final Integer page,
            final int limit, final String search, final Handler<Either<String, JsonArray>> result) {
        final QueryBuilder accessQuery = QueryBuilder.start("blog.$id").is(blogId).put("state").is(state.name());
        final JsonObject sort = new JsonObject().put("modified", -1);
        final JsonObject projection = defaultKeys.copy();
        projection.remove("content");

        final Handler<Message<JsonObject>> finalHandler = new Handler<Message<JsonObject>>() {
            @Override
            public void handle(Message<JsonObject> event) {
                result.handle(Utils.validResults(event));
            }
        };

        final QueryBuilder query = getQueryListBuilder(search, result, accessQuery);

        if (query != null) {

            if (StateType.PUBLISHED.equals(state)) {
                if (limit > 0 && page == null) {
                    mongo.find(POST_COLLECTION, MongoQueryBuilder.build(query), sort, projection, 0, limit, limit,
                            finalHandler);
                } else if (page == null) {
                    mongo.find(POST_COLLECTION, MongoQueryBuilder.build(query), sort, projection, finalHandler);
                } else {
                    final int skip = (0 == page) ? -1 : page * limit;
                    final JsonObject sortPag = new JsonObject().put("sorted", -1);
                    mongo.find(POST_COLLECTION, MongoQueryBuilder.build(query), sortPag, projection, skip, limit,
                            limit, finalHandler);
                }
            } else {
                QueryBuilder query2 = getDefautQueryBuilderForList(blogId, user, true);
                mongo.count("blogs", MongoQueryBuilder.build(query2), new Handler<Message<JsonObject>>() {
                    @Override
                    public void handle(Message<JsonObject> event) {
                        JsonObject res = event.body();

                        if ((res != null && "ok".equals(res.getString("status")) && 1 != res.getInteger("count"))
                                || StateType.DRAFT.equals(state)) {
                            accessQuery.put("author.userId").is(user.getUserId());
                        }

                        final QueryBuilder listQuery = getQueryListBuilder(search, result, accessQuery);
                        if (limit > 0 && page == null) {
                            mongo.find(POST_COLLECTION, MongoQueryBuilder.build(listQuery), sort, projection, 0,
                                    limit, limit, finalHandler);
                        } else if (page == null) {
                            mongo.find(POST_COLLECTION, MongoQueryBuilder.build(listQuery), sort, projection,
                                    finalHandler);
                        } else {
                            final JsonObject sortPag = new JsonObject().put("sorted", -1);
                            final int skip = (0 == page) ? -1 : page * limit;
                            mongo.find(POST_COLLECTION, MongoQueryBuilder.build(listQuery), sortPag, projection,
                                    skip, limit, limit, finalHandler);
                        }
                    }
                });
            }
        }
    }

    private QueryBuilder getQueryListBuilder(String search, Handler<Either<String, JsonArray>> result,
            QueryBuilder accessQuery) {
        final QueryBuilder query;
        if (!StringUtils.isEmpty(search)) {
            final List<String> searchWords = DefaultBlogService.checkAndComposeWordFromSearchText(search,
                    this.searchWordMinSize);
            if (!searchWords.isEmpty()) {
                final QueryBuilder searchQuery = new QueryBuilder();
                searchQuery.text(MongoDbSearchService.textSearchedComposition(searchWords));
                query = new QueryBuilder().and(accessQuery.get(), searchQuery.get());
            } else {
                query = null;
                //empty result (no word to search)
                result.handle(new Either.Right<String, JsonArray>(new JsonArray()));
            }
        } else {
            query = accessQuery;
        }
        return query;
    }

    @Override
    public void listOne(String blogId, String postId, final UserInfos user,
            final Handler<Either<String, JsonArray>> result) {
        final QueryBuilder query = QueryBuilder.start("blog.$id").is(blogId).put("_id").is(postId);
        final QueryBuilder isManagerQuery = getDefautQueryBuilderForList(blogId, user, true);
        final JsonObject sort = new JsonObject().put("modified", -1);
        final JsonObject projection = defaultKeys.copy();
        projection.remove("content");

        final Handler<Message<JsonObject>> finalHandler = new Handler<Message<JsonObject>>() {
            @Override
            public void handle(Message<JsonObject> event) {
                result.handle(Utils.validResults(event));
            }
        };

        mongo.count("blogs", MongoQueryBuilder.build(isManagerQuery), new Handler<Message<JsonObject>>() {
            public void handle(Message<JsonObject> event) {
                JsonObject res = event.body();
                if (res == null || !"ok".equals(res.getString("status"))) {
                    result.handle(new Either.Left<String, JsonArray>(event.body().encodePrettily()));
                    return;
                }
                boolean isManager = 1 == res.getInteger("count", 0);

                query.or(QueryBuilder.start("state").is(StateType.PUBLISHED.name()).get(),
                        QueryBuilder.start()
                                .and(QueryBuilder.start("author.userId").is(user.getUserId()).get(),
                                        QueryBuilder.start("state").is(StateType.DRAFT.name()).get())
                                .get(),
                        isManager ? QueryBuilder.start("state").is(StateType.SUBMITTED.name()).get()
                                : QueryBuilder.start()
                                        .and(QueryBuilder.start("author.userId").is(user.getUserId()).get(),
                                                QueryBuilder.start("state").is(StateType.SUBMITTED.name()).get())
                                        .get());
                mongo.find(POST_COLLECTION, MongoQueryBuilder.build(query), sort, projection, finalHandler);
            }
        });
    }

    private QueryBuilder getDefautQueryBuilderForList(String blogId, UserInfos user, boolean manager) {
        List<DBObject> groups = new ArrayList<>();
        if (manager) {
            groups.add(QueryBuilder.start("userId").is(user.getUserId()).put("manager").is(true).get());
        } else {
            groups.add(QueryBuilder.start("userId").is(user.getUserId()).put(this.listPostAction).is(true).get());
        }
        for (String gpId : user.getGroupsIds()) {
            if (manager) {
                groups.add(QueryBuilder.start("groupId").is(gpId).put("manager").is(true).get());
            } else {
                groups.add(QueryBuilder.start("groupId").is(gpId).put(this.listPostAction).is(true).get());
            }
        }
        return QueryBuilder.start("_id").is(blogId)
                .or(QueryBuilder.start("author.userId").is(user.getUserId()).get(), QueryBuilder.start("shared")
                        .elemMatch(new QueryBuilder().or(groups.toArray(new DBObject[groups.size()])).get()).get());
    }

    @Override
    public void submit(String blogId, String postId, UserInfos user,
            final Handler<Either<String, JsonObject>> result) {
        QueryBuilder query = QueryBuilder.start("_id").is(postId).put("blog.$id").is(blogId).put("state")
                .is(StateType.DRAFT.name()).put("author.userId").is(user.getUserId());
        final JsonObject q = MongoQueryBuilder.build(query);
        JsonObject keys = new JsonObject().put("blog", 1).put("firstPublishDate", 1);
        JsonArray fetch = new JsonArray().add("blog");
        mongo.findOne(POST_COLLECTION, q, keys, fetch, new Handler<Message<JsonObject>>() {
            @Override
            public void handle(Message<JsonObject> event) {
                final JsonObject res = event.body().getJsonObject("result", new JsonObject());
                if ("ok".equals(event.body().getString("status")) && res.size() > 0) {
                    BlogService.PublishType type = Utils.stringToEnum(
                            res.getJsonObject("blog", new JsonObject()).getString("publish-type"),
                            BlogService.PublishType.RESTRAINT, BlogService.PublishType.class);
                    final StateType state = (BlogService.PublishType.RESTRAINT.equals(type)) ? StateType.SUBMITTED
                            : StateType.PUBLISHED;
                    MongoUpdateBuilder updateQuery = new MongoUpdateBuilder().set("state", state.name());

                    // if IMMEDIATE published post, first publishing must define the first published date
                    if (StateType.PUBLISHED.equals(state) && res.getJsonObject("firstPublishDate") == null) {
                        updateQuery = updateQuery.set("firstPublishDate", MongoDb.now()).set("sorted",
                                MongoDb.now());
                    }

                    mongo.update(POST_COLLECTION, q, updateQuery.build(), new Handler<Message<JsonObject>>() {
                        @Override
                        public void handle(Message<JsonObject> res) {
                            res.body().put("state", state.name());
                            result.handle(Utils.validResult(res));
                        }
                    });
                } else {
                    result.handle(Utils.validResult(event));
                }
            }
        });
    }

    @Override
    public void publish(final String blogId, final String postId,
            final Handler<Either<String, JsonObject>> result) {
        QueryBuilder query = QueryBuilder.start("_id").is(postId).put("blog.$id").is(blogId);
        MongoUpdateBuilder updateQuery = new MongoUpdateBuilder().set("state", StateType.PUBLISHED.name());
        mongo.update(POST_COLLECTION, MongoQueryBuilder.build(query), updateQuery.build(),
                MongoDbResult.validActionResultHandler(new Handler<Either<String, JsonObject>>() {
                    public void handle(Either<String, JsonObject> event) {
                        if (event.isLeft()) {
                            result.handle(event);
                            return;
                        }

                        QueryBuilder query = QueryBuilder.start("_id").is(postId).put("blog.$id").is(blogId)
                                .put("firstPublishDate").exists(false);

                        MongoUpdateBuilder updateQuery = new MongoUpdateBuilder()
                                .set("firstPublishDate", MongoDb.now()).set("sorted", MongoDb.now());

                        mongo.update(POST_COLLECTION, MongoQueryBuilder.build(query), updateQuery.build(),
                                MongoDbResult.validActionResultHandler(result));
                    }
                }));
    }

    @Override
    public void unpublish(String postId, final Handler<Either<String, JsonObject>> result) {
        QueryBuilder query = QueryBuilder.start("_id").is(postId);
        MongoUpdateBuilder updateQuery = new MongoUpdateBuilder().set("state", StateType.DRAFT.name());
        mongo.update(POST_COLLECTION, MongoQueryBuilder.build(query), updateQuery.build(),
                new Handler<Message<JsonObject>>() {
                    @Override
                    public void handle(Message<JsonObject> res) {
                        result.handle(Utils.validResult(res));
                    }
                });
    }

    @Override
    public void addComment(String blogId, String postId, final String comment, final UserInfos author,
            final Handler<Either<String, JsonObject>> result) {
        if (comment == null || comment.trim().isEmpty()) {
            result.handle(new Either.Left<String, JsonObject>("Validation error : invalid comment."));
            return;
        }
        QueryBuilder query = QueryBuilder.start("_id").is(postId).put("blog.$id").is(blogId);
        final JsonObject q = MongoQueryBuilder.build(query);
        JsonObject keys = new JsonObject().put("blog", 1);
        JsonArray fetch = new JsonArray().add("blog");
        mongo.findOne(POST_COLLECTION, q, keys, fetch, new Handler<Message<JsonObject>>() {
            @Override
            public void handle(Message<JsonObject> event) {
                if ("ok".equals(event.body().getString("status"))
                        && event.body().getJsonObject("result", new JsonObject()).size() > 0) {
                    BlogService.CommentType type = Utils.stringToEnum(
                            event.body().getJsonObject("result").getJsonObject("blog", new JsonObject())
                                    .getString("comment-type"),
                            BlogService.CommentType.RESTRAINT, BlogService.CommentType.class);
                    if (BlogService.CommentType.NONE.equals(type)) {
                        result.handle(new Either.Left<String, JsonObject>("Comments are disabled for this blog."));
                        return;
                    }
                    StateType s = BlogService.CommentType.IMMEDIATE.equals(type) ? StateType.PUBLISHED
                            : StateType.SUBMITTED;
                    JsonObject user = new JsonObject().put("userId", author.getUserId())
                            .put("username", author.getUsername()).put("login", author.getLogin());
                    JsonObject c = new JsonObject().put("comment", comment).put("id", UUID.randomUUID().toString())
                            .put("state", s.name()).put("author", user).put("created", MongoDb.now());
                    MongoUpdateBuilder updateQuery = new MongoUpdateBuilder().push("comments", c);
                    mongo.update(POST_COLLECTION, q, updateQuery.build(), new Handler<Message<JsonObject>>() {
                        @Override
                        public void handle(Message<JsonObject> res) {
                            result.handle(Utils.validResult(res));
                        }
                    });
                } else {
                    result.handle(Utils.validResult(event));
                }
            }
        });
    }

    @Override
    public void deleteComment(final String blogId, final String commentId, final UserInfos user,
            final Handler<Either<String, JsonObject>> result) {
        QueryBuilder query2 = getDefautQueryBuilderForList(blogId, user, false);
        mongo.count("blogs", MongoQueryBuilder.build(query2), new Handler<Message<JsonObject>>() {
            @Override
            public void handle(Message<JsonObject> event) {
                JsonObject res = event.body();
                QueryBuilder tmp = QueryBuilder.start("id").is(commentId);
                if (res != null && "ok".equals(res.getString("status")) && 1 != res.getInteger("count")) {
                    tmp.put("author.userId").is(user.getUserId());
                }
                QueryBuilder query = QueryBuilder.start("blog.$id").is(blogId).put("comments").elemMatch(tmp.get());
                JsonObject c = new JsonObject().put("id", commentId);
                MongoUpdateBuilder queryUpdate = new MongoUpdateBuilder().pull("comments", c);
                mongo.update(POST_COLLECTION, MongoQueryBuilder.build(query), queryUpdate.build(),
                        new Handler<Message<JsonObject>>() {
                            @Override
                            public void handle(Message<JsonObject> res) {
                                result.handle(Utils.validResult(res));
                            }
                        });
            }
        });
    }

    @Override
    public void listComment(String blogId, String postId, final UserInfos user,
            final Handler<Either<String, JsonArray>> result) {
        final QueryBuilder query = QueryBuilder.start("_id").is(postId).put("blog.$id").is(blogId);
        JsonObject keys = new JsonObject().put("comments", 1).put("blog", 1);
        JsonArray fetch = new JsonArray().add("blog");
        mongo.findOne(POST_COLLECTION, MongoQueryBuilder.build(query), keys, fetch,
                new Handler<Message<JsonObject>>() {
                    @Override
                    public void handle(Message<JsonObject> event) {
                        JsonArray comments = new JsonArray();
                        if ("ok".equals(event.body().getString("status"))
                                && event.body().getJsonObject("result", new JsonObject()).size() > 0) {
                            JsonObject res = event.body().getJsonObject("result");
                            boolean userIsManager = userIsManager(user, res.getJsonObject("blog"));
                            for (Object o : res.getJsonArray("comments", new JsonArray())) {
                                if (!(o instanceof JsonObject))
                                    continue;
                                JsonObject j = (JsonObject) o;
                                if (userIsManager || StateType.PUBLISHED.name().equals(j.getString("state"))
                                        || user.getUserId().equals(
                                                j.getJsonObject("author", new JsonObject()).getString("userId"))) {
                                    comments.add(j);
                                }
                            }
                        }
                        result.handle(new Either.Right<String, JsonArray>(comments));
                    }
                });
    }

    private boolean userIsManager(UserInfos user, JsonObject res) {
        if (res != null && res.getJsonArray("shared") != null) {
            for (Object o : res.getJsonArray("shared")) {
                if (!(o instanceof JsonObject))
                    continue;
                JsonObject json = (JsonObject) o;
                return json != null && json.getBoolean("manager", false)
                        && (user.getUserId().equals(json.getString("userId"))
                                || user.getGroupsIds().contains(json.getString("groupId")));
            }
        }
        return false;
    }

    @Override
    public void publishComment(String blogId, String commentId, final Handler<Either<String, JsonObject>> result) {
        QueryBuilder query = QueryBuilder.start("blog.$id").is(blogId).put("comments")
                .elemMatch(QueryBuilder.start("id").is(commentId).get());
        MongoUpdateBuilder updateQuery = new MongoUpdateBuilder().set("comments.$.state",
                StateType.PUBLISHED.name());
        mongo.update(POST_COLLECTION, MongoQueryBuilder.build(query), updateQuery.build(),
                new Handler<Message<JsonObject>>() {
                    @Override
                    public void handle(Message<JsonObject> res) {
                        result.handle(Utils.validResult(res));
                    }
                });
    }

    private boolean validationError(Handler<Either<String, JsonObject>> result, JsonObject b) {
        if (b == null) {
            result.handle(new Either.Left<String, JsonObject>("Validation error : invalids fields."));
            return true;
        }
        return false;
    }

}