Package com.streamreduce.rest.resource.api

Source Code of com.streamreduce.rest.resource.api.MessageResource

/*
* Copyright 2012 Nodeable Inc
*
*    Licensed under the Apache License, Version 2.0 (the "License");
*    you may not use this file except in compliance with the License.
*    You may obtain a copy of the License at
*
*        http://www.apache.org/licenses/LICENSE-2.0
*
*    Unless required by applicable law or agreed to in writing, software
*    distributed under the License is distributed on an "AS IS" BASIS,
*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*    See the License for the specific language governing permissions and
*    limitations under the License.
*/

package com.streamreduce.rest.resource.api;

import com.streamreduce.core.event.EventId;
import com.streamreduce.core.model.Event;
import com.streamreduce.core.model.User;
import com.streamreduce.core.model.messages.MessageComment;
import com.streamreduce.core.model.messages.SobaMessage;
import com.streamreduce.core.service.EmailService;
import com.streamreduce.core.service.exception.MessageNotFoundException;
import com.streamreduce.core.service.exception.TargetNotFoundException;
import com.streamreduce.rest.dto.response.MessageCommentResponseDTO;
import com.streamreduce.rest.dto.response.MessageCommentsResponseDTO;
import com.streamreduce.rest.dto.response.SobaMessageResponseDTO;
import com.streamreduce.rest.resource.ErrorMessages;
import com.streamreduce.util.MessageUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import net.sf.json.JSONObject;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Path("api/messages")
@Produces(MediaType.APPLICATION_JSON)
public class MessageResource extends AbstractTagableSobaResource {

    @Autowired
    private EmailService emailService;

    /**
     * Creates a new USER generated message.  Use created messages will show up as "from" the user who created it, either as a DM or an
     * Account level message.
     *
     * @param json - The message to create
     * @return - Response.Status.CREATED and a DTO of SobaMessage that was created.
     * @response.representation.201.doc Returned when the message was successfully created and sent
     * @response.representation.400.doc Returned when the client attempts to create a user message that is empty or sends to an invalid target.
     */
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public Response addMessage(JSONObject json) {

        String message = getJSON(json, "message");

        if (isEmpty(message)) {
            return error("Message payload can not be empty", Response.status(Response.Status.BAD_REQUEST));
        }

        SobaMessage sobaMessage;
        User sender = applicationManager.getSecurityService().getCurrentUser();
        Map<String, Object> eventContext = new HashMap<>();

        eventContext.put("message", message);
        eventContext.put("payload", json);

        Event event = applicationManager.getEventService().createEvent(EventId.USER_MESSAGE, null, eventContext);

        try {
            sobaMessage = applicationManager.getMessageService().sendUserMessage(event, sender, message);
        } catch (TargetNotFoundException e) {
            return error(e.getMessage(), Response.status(Response.Status.BAD_REQUEST));
        }

        return Response
                .status(Response.Status.CREATED)
                .entity(SobaMessageResponseDTO.fromSobaMessage(sobaMessage))
                .build();
    }

    /**
     * Retrieves all messages for the client.
     *
     * @param after     - time in ms, after this date
     * @param before    - time in ms, before this date
     * @param limit     - only return this value, optional, but capped at something like 100 if set to 0
     * @param ascending - default to true
     * @param search    - string to search on
     * @param fullText  - get the full message payload, or else truncate it
     * @param hashtags  - limits results to those that only contain all of the specified hashtags
     * @param sender    - limits results to only those messages whose sender is specified.  sender can represent the id or alias of the sender
     * @return DTO of messages
     * @response.representation.200.doc Returned when all messages were successfully rendered
     */
    @GET
    public Response getAllMessages(@QueryParam("after") Long after, @QueryParam("before") Long before,
                                   @QueryParam("limit") int limit, @DefaultValue("true") @QueryParam("ascending") boolean ascending,
                                   @QueryParam("search") String search, @QueryParam("fullText") boolean fullText,
                                   @QueryParam("hashtag") List<String> hashtags, @QueryParam("sender") String sender,
                                   @QueryParam("excludeInsights") boolean excludeInsights) {

        User user = applicationManager.getSecurityService().getCurrentUser();
        List<SobaMessage> allMessages = applicationManager.getMessageService().getAllMessages(user, after, before, limit, ascending, search, hashtags, sender, excludeInsights);

        return Response
                .ok(SobaMessageResponseDTO.fromSobaMessages(allMessages, fullText))
                .build();

    }

    /**
     * Retreives the full contents of a message given the message id.
     *
     * @param messageId -- messageId
     * @return -  will only return the message if you can access it (ie, if it's a DIRECT message to you
     *         or a subscriber message, etc.
     * @response.representation.200.doc Returned when all direct messages were successfully rendered
     * @response.representation.404.doc Returned when a message could not be found given the ID for the client
     */
    @GET
    @Path("{messageId}")
    public Response getMessageById(@PathParam("messageId") ObjectId messageId) {

        User user = applicationManager.getSecurityService().getCurrentUser();
        SobaMessage sobaMessage;

        try {
            sobaMessage = applicationManager.getMessageService().getMessage(user.getAccount(), messageId);

        } catch (MessageNotFoundException e) {
            return error(e.getMessage(), Response.status(Response.Status.NOT_FOUND));
        }

        return Response
                .ok(SobaMessageResponseDTO.fromSobaMessage(sobaMessage))
                .build();

    }

    @DELETE
    @Path("{messageId}")
    public Response deleteMessage(@PathParam("messageId") ObjectId messageId) {
        User user = applicationManager.getSecurityService().getCurrentUser();

        try {
            SobaMessage sobaMessage = applicationManager.getMessageService().getMessage(user.getAccount(), messageId);
            // users can only nullify a message from a resource they own
            if (sobaMessage.getOwnerId().equals(user.getId())) {
                applicationManager.getMessageService().nullifyMessage(user, sobaMessage);
            } else {
                return error(ErrorMessages.APPLICATION_ACCESS_DENIED, Response.status(Response.Status.BAD_REQUEST));
            }

        } catch (MessageNotFoundException e) {
            return error(e.getMessage(), Response.status(Response.Status.NOT_FOUND));
        }

        return Response.ok().build();
    }


    /**
     * Add a comment or a tag (via the comment) to a given message.
     *
     * @param messageId - messageId
     * @param json      - the comment payload
     * @return no content
     * @response.representation.204.doc Returned when a comment or tag was added to a message.
     * @response.representation.400.doc Returned when the client attempts to add an empty comment
     * @response.representation.404.doc Returned when a message being added could not be found given the ID for the client
     */
    @PUT
    @Path("{messageId}/comment")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response addCommentToMessage(@PathParam("messageId") ObjectId messageId, JSONObject json) {

        String comment = getJSON(json, "comment");

        if (isEmpty(comment)) {
            return error(ErrorMessages.MISSING_REQUIRED_FIELD + "comment", Response.status(Response.Status.BAD_REQUEST));
        }

        User user = applicationManager.getSecurityService().getCurrentUser();

        // check if the user added any tags
        MessageUtils.ParsedMessage parsedMessage = MessageUtils.parseMessage(comment);
        Set<String> hashtags = parsedMessage.getTags();

        MessageComment messageComment = new MessageComment(user, parsedMessage.getMessage());

        try {
            SobaMessage sobaMessage = applicationManager.getMessageService().getMessage(user.getAccount(), messageId);
            // this is now a conversation, so add that tag
            hashtags.add("#conversation");
            applicationManager.getMessageService().addCommentToMessage(user.getAccount(), sobaMessage.getId(), messageComment, hashtags);

        } catch (MessageNotFoundException e) {
            return error(e.getMessage(), Response.status(Response.Status.NOT_FOUND));
        }

        return Response
                .status(Response.Status.NO_CONTENT)
                .build();
    }

    /**
     * Retrieves all comments that have been added to a given message
     *
     * @param messageId the id of the messsage that comments will be returned for
     * @return message comment DTO
     * @response.representation.200.doc Returned when all comments to a message were succesfully rendered
     * @response.representation.404.doc Returned when the message does not exist
     */
    @GET
    @Path("{messageId}/comment")
    public Response getCommentsForMessage(@PathParam("messageId") ObjectId messageId) {

        User user = applicationManager.getSecurityService().getCurrentUser();
        SobaMessage sobaMessage;

        try {
            sobaMessage = applicationManager.getMessageService().getMessage(user.getAccount(), messageId);

        } catch (MessageNotFoundException e) {
            return error(e.getMessage(), Response.status(Response.Status.NOT_FOUND));
        }

        MessageCommentsResponseDTO dto = new MessageCommentsResponseDTO();
        List<MessageCommentResponseDTO> allComments = new ArrayList<>();
        for (MessageComment comment : sobaMessage.getComments()) {
            allComments.add(comment.toDTO());
        }

        dto.setComments(allComments);

        return Response
                .ok(dto)
                .build();
    }


    /**
     * Remove the comment from the User on the timestamp indicated, since we don't have a messageId
     *
     * @return
     */
    @DELETE
    @Path("{messageId}/comment/{created}")
    public Response deleteCommentForMessage(@PathParam("messageId") ObjectId messageId, @PathParam("created") Long created) {

        User user = applicationManager.getSecurityService().getCurrentUser();
        try {
            SobaMessage sobaMessage = applicationManager.getMessageService().getMessage(user.getAccount(), messageId);
            for (MessageComment messageComment : sobaMessage.getComments()) {
                // find the message comment to update
                if (messageComment.getSenderId().equals(user.getId()) && messageComment.getCreated().equals(created)) {
                    applicationManager.getMessageService().nullifyMessageComment(user, sobaMessage, messageComment);
                    break;
                }
            }

        } catch (MessageNotFoundException e) {
            return error(e.getMessage(), Response.status(Response.Status.NOT_FOUND));
        }

        return Response
                .ok()
                .build();

    }

    /**
     * Applies a hashtag directly to a message
     *
     * @param messageId - internal Id of message
     * @param json      - hasstag dto
     * @return - 200 OK
     * @response.representation.200.doc Returned when a hashtag was successfully added to a message
     * @response.representation.400.doc Returned when a client attempts to add an empty hashtag or the message can not be found
     */
    @POST
    @Path("{messageId}/hashtag")
    @Consumes(MediaType.APPLICATION_JSON)
    @Override
    public Response addTag(@PathParam("messageId") String messageId, JSONObject json) {

        String hashtag = getJSON(json, HASHTAG);

        if (isEmpty(hashtag)) {
            return error("Hashtag payload is empty", Response.status(Response.Status.BAD_REQUEST));
        }

        User user = applicationManager.getSecurityService().getCurrentUser();

        try {
            applicationManager.getMessageService().addHashtagToMessage(user.getAccount(), new ObjectId(messageId),
                    hashtag);

        } catch (MessageNotFoundException e) {
            return error(e.getMessage(), Response.status(Response.Status.BAD_REQUEST));
        }

        return Response
                .ok()
                .build();
    }


    /**
     * Retrieves a list of all hashtags currently applied to a given message.
     *
     * @param messageId
     * @response.representation.200.doc Returned when a hashtags for the given message were successfully rendered
     * @response.representation.400.doc Returned the client does not have access to the message
     * @response.representation.404.doc Returned when the message that hashtags are requested for can't be found
     */
    @GET
    @Path("{messageId}/hashtag")
    @Override
    public Response getTags(@PathParam("messageId") String messageId) {

        User user = applicationManager.getSecurityService().getCurrentUser();
        Set<String> tags;
        try {
            SobaMessage sobaMessage = applicationManager.getMessageService().getMessage(user.getAccount(),
                    new ObjectId(messageId));
            tags = sobaMessage.getHashtags();

        } catch (MessageNotFoundException e) {
            return error(e.getMessage(), Response.status(Response.Status.NOT_FOUND));
        }

        return Response
                .ok(tags)
                .build();

    }


    /**
     * Remove a hashtag from a given message.
     *
     * @param messageId
     * @param hashtag
     * @return
     * @response.representation.200.doc Returned when the hashtag for the message was removed successfully.
     * @response.representation.400.doc Returned the client does not have access to the message
     * @response.representation.404.doc Returned when the message that hashtags are requested for can't be found
     */
    @DELETE
    @Path("{messageId}/hashtag/{tagname}")
    @Override
    public Response removeTag(@PathParam("messageId") String messageId, @PathParam("tagname") String hashtag) {

        if (isEmpty(hashtag)) {
            return error("Hashtag payload is empty", Response.status(Response.Status.BAD_REQUEST));
        }

        User user = applicationManager.getSecurityService().getCurrentUser();

        try {
            applicationManager.getMessageService().removeHashtagFromMessage(user.getAccount(), new ObjectId(messageId),
                    hashtag);

        } catch (MessageNotFoundException e) {
            return error(e.getMessage(), Response.status(Response.Status.BAD_REQUEST));
        }
        return Response.ok().build();
    }

    @POST
    @Path("{messageId}/email")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response email(@PathParam("messageId") ObjectId messageId, JSONObject json) {

        User user = applicationManager.getSecurityService().getCurrentUser();

        SobaMessage message;
        try {
            message = applicationManager.getMessageService().getMessage(user.getAccount(), messageId);
        }
        catch (MessageNotFoundException mnfe) {
            logger.error("Unable to find message with ID {}", messageId);
            return Response.status(404).build();
        }

        emailService.sendUserMessageEmail(user, message, json);

        return Response
                .ok()
                .build();
    }
}
TOP

Related Classes of com.streamreduce.rest.resource.api.MessageResource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.