org.jtalks.jcommune.web.controller.AvatarController.java Source code

Java tutorial

Introduction

Here is the source code for org.jtalks.jcommune.web.controller.AvatarController.java

Source

/**
 * Copyright (C) 2011  JTalks.org Team
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * This library 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
 * Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

package org.jtalks.jcommune.web.controller;

import org.joda.time.DateTime;
import org.jtalks.jcommune.model.entity.JCUser;
import org.jtalks.jcommune.plugin.api.exceptions.NotFoundException;
import org.jtalks.jcommune.service.UserService;
import org.jtalks.jcommune.service.exceptions.ImageProcessException;
import org.jtalks.jcommune.web.util.ImageControllerUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.MessageSource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;

/**
 * Controller for processing avatar related request.
 *
 * @author Alexandre Teterin
 * @author Anuar Nurmakanov
 * @author Andrei Alikov
 */
@Controller
public class AvatarController extends ImageUploadController {
    private UserService userService;
    private ImageControllerUtils avatarControllerUtils;

    /**
     * Constructor for controller instantiating, dependencies injected via autowiring.
     *
     * @param userService           to manipulate user-related data
     * @param avatarControllerUtils utility object for image-related functions
     * @param messageSource         to resolve locale-dependent messages
     */
    @Autowired
    public AvatarController(UserService userService,
            @Qualifier("avatarControllerUtils") ImageControllerUtils avatarControllerUtils,
            MessageSource messageSource) {
        super(messageSource);

        this.userService = userService;
        this.avatarControllerUtils = avatarControllerUtils;
    }

    /**
     * Process avatar file from request and return avatar preview in response.
     * Used for IE, Opera specific request processing.
     *
     * @param file file, that contains uploaded image
     * @return ResponseEntity
     * @throws IOException           defined in the JsonFactory implementation,
     *                               caller must implement exception processing
     * @throws ImageProcessException if error occurred while image processing
     */
    @RequestMapping(value = "/users/IFrameAvatarpreview", method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<String> uploadAvatar(@RequestParam(value = "qqfile") MultipartFile file)
            throws IOException, ImageProcessException {
        return createPreviewOfImage(file, avatarControllerUtils);
    }

    /**
     * Process avatar file from request and return avatar preview in response.
     * Used for FF, Chrome specific request processing
     *
     * @param bytes    input avatar data
     * @param response servlet response
     * @return response content
     * @throws ImageProcessException if error occurred while image processing
     */
    @RequestMapping(value = "/users/XHRavatarpreview", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, String> uploadAvatar(@RequestBody byte[] bytes, HttpServletResponse response)
            throws ImageProcessException {
        return createPreviewOfImage(bytes, response, avatarControllerUtils);
    }

    /**
     * Write user avatar in response for rendering it on html pages.
     *
     * @param request  servlet request
     * @param response servlet response
     * @param id       user database identifier
     * @throws NotFoundException if user with given encodedUsername not found
     * @throws IOException       throws if an output exception occurred
     */
    @RequestMapping(value = "/users/{id}/avatar", method = RequestMethod.GET)
    public void renderAvatar(HttpServletRequest request, HttpServletResponse response, @PathVariable Long id)
            throws NotFoundException, IOException {
        JCUser user = userService.get(id);

        Date ifModifiedDate = super.getIfModifiedSinceDate(request.getHeader(IF_MODIFIED_SINCE_HEADER));
        // using 0 unix time if avatar has never changed (the date is null). It's easier to work with something
        // non-null than to check for null all the time.
        DateTime avatarLastModificationTime = defaultIfNull(user.getAvatarLastModificationTime(), new DateTime(0));
        // if-modified-since header doesn't include milliseconds, so if it floors the value (millis = 0), then
        // actual modification date will always be after the if-modified-since and we'll always be returning avatar
        avatarLastModificationTime = avatarLastModificationTime.withMillisOfSecond(0);
        if (avatarLastModificationTime.isAfter(ifModifiedDate.getTime())) {
            byte[] avatar = user.getAvatar();
            response.setContentType("image/jpeg");
            response.setContentLength(avatar.length);
            response.getOutputStream().write(avatar);
        } else {
            response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        }
        setupAvatarHeaders(response, new Date(avatarLastModificationTime.getMillis()));
    }

    /**
     * Prepare response with default user avatar
     *
     * @return JSON string with default user avatar
     * @throws ImageProcessException due to common avatar processing error
     * @throws IOException           defined in the JsonFactory implementation, caller must implement exception
     *                               processing
     */
    @RequestMapping(value = "/defaultAvatar", method = RequestMethod.GET)
    @ResponseBody
    public String getDefaultAvatar() throws ImageProcessException, IOException {
        Map<String, String> responseContent = new HashMap<>();
        avatarControllerUtils.prepareNormalResponse(avatarControllerUtils.getDefaultImage(), responseContent);
        return avatarControllerUtils.getResponceJSONString(responseContent);
    }
}