io.curly.advisor.web.ReviewResourceController.java Source code

Java tutorial

Introduction

Here is the source code for io.curly.advisor.web.ReviewResourceController.java

Source

/*
 *        Copyright 2015 the original author or authors.
 *
 *    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 io.curly.advisor.web;

import io.curly.advisor.command.ReviewBusWrapper;
import io.curly.advisor.command.ReviewHystrixCommands;
import io.curly.advisor.model.Review;
import io.curly.advisor.model.ReviewEntity;
import io.curly.advisor.web.hateoas.ReviewResource;
import io.curly.advisor.web.hateoas.ReviewResourceAssembler;
import io.curly.commons.github.GitHubAuthentication;
import io.curly.commons.github.User;
import io.curly.commons.web.BadRequestException;
import io.curly.commons.web.ModelErrors;
import io.curly.commons.web.UnauthorizedException;
import io.curly.commons.web.hateoas.MediaTypes;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.data.web.PageableDefault;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.ExposesResourceFor;
import org.springframework.hateoas.PagedResources;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;
import reactor.bus.Event;
import reactor.bus.EventBus;
import rx.Observable;

import javax.validation.Valid;

import static io.curly.commons.rx.RxResult.defer;

/**
 * @author Joao Pedro Evangelista
 */
@RestController
@RequestMapping(value = "/reviews")
@ExposesResourceFor(Review.class)
public class ReviewResourceController {

    private final ReviewResourceAssembler reviewResourceAssembler;

    private final ReviewHystrixCommands commands;

    private final EventBus eventBus;

    @Autowired
    public ReviewResourceController(ReviewResourceAssembler reviewResourceAssembler, ReviewHystrixCommands commands,
            EventBus eventBus) {
        this.reviewResourceAssembler = reviewResourceAssembler;
        this.commands = commands;
        this.eventBus = eventBus;
    }

    @RequestMapping(value = "/artifact/{artifact}", method = RequestMethod.GET, produces = MediaTypes.HAL_JSON)
    public DeferredResult<ResponseEntity<PagedResources<ReviewResource>>> getAllByArtifact(
            @PageableDefault(20) Pageable pageable, @PathVariable("artifact") String artifact,
            PagedResourcesAssembler<Review> pagedResourcesAssembler) {
        if (!ObjectId.isValid(artifact))
            throw new BadRequestException(artifact + " is not in a valid format.");

        final Observable<ResponseEntity<PagedResources<ReviewResource>>> reviewEntity = commands
                .findAllByArtifact(pageable, artifact)
                .map(reviews -> pagedResourcesAssembler.toResource(reviews, reviewResourceAssembler))
                .map(ResponseEntity::ok);
        return defer(reviewEntity);
    }

    @RequestMapping(value = "/owned/{review}", method = RequestMethod.GET, produces = MediaTypes.HAL_JSON)
    public DeferredResult<ResponseEntity<ReviewResource>> getForUser(@GitHubAuthentication User user,
            @PathVariable("review") String review) {
        if (!ObjectId.isValid(review))
            throw new BadRequestException(review + " is not in a valid format.");
        if (user == null)
            throw new UnauthorizedException("Cannot get user in this context!");
        final Observable<ResponseEntity<ReviewResource>> entity = commands.findByOwner(user, review)
                .map(reviewOptional -> reviewOptional
                        .<ResourceNotFoundException>orElseThrow(ResourceNotFoundException::new))
                .map(reviewResourceAssembler::toResource).map(ResponseEntity::ok);

        return defer(entity);
    }

    @RequestMapping(method = { RequestMethod.POST, RequestMethod.PUT })
    public ResponseEntity<?> save(@Valid @RequestBody ReviewEntity reviewEntity, @GitHubAuthentication User user,
            BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return new ResponseEntity<>(new ModelErrors(bindingResult), HttpStatus.BAD_REQUEST);
        }
        eventBus.notify("review.post", Event.wrap(new ReviewBusWrapper(reviewEntity, user)));
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @RequestMapping(value = "/owned", method = RequestMethod.GET)
    public DeferredResult<ResponseEntity<PagedResources<ReviewResource>>> getAllByUser(
            @GitHubAuthentication User user, @PageableDefault(20) Pageable pageable,
            PagedResourcesAssembler<Review> pagedAssembler) {
        if (user == null)
            throw new UnauthorizedException("Cannot find user in current context!");
        return defer(commands.findAllByOwner(user, pageable)
                .map(reviews -> pagedAssembler.toResource(reviews, reviewResourceAssembler))
                .map(ResponseEntity::ok));
    }
}