com.couchbase.trombi.controllers.CoworkerController.java Source code

Java tutorial

Introduction

Here is the source code for com.couchbase.trombi.controllers.CoworkerController.java

Source

/*
 * Copyright (c) 2016 Couchbase, 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.couchbase.trombi.controllers;

import java.net.URI;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.subdoc.MutateInBuilder;
import com.couchbase.trombi.TrombinoscopeApplication;
import com.couchbase.trombi.data.CoworkerRepository;
import com.couchbase.trombi.domain.Coworker;
import com.couchbase.trombi.domain.Location;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Point;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

/**
 * A REST Controller to perform CRUD on {@link Coworker}.
 *
 * @author Simon Basl
 */
@RestController
@RequestMapping("/api/coworkers")
public class CoworkerController {

    private final CoworkerRepository repository;
    private final Bucket bucket;

    @Autowired
    public CoworkerController(CoworkerRepository repository, Bucket bucket) {
        this.repository = repository;
        this.bucket = bucket;
    }

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public Iterable<Coworker> coworkers() {
        return repository.findAll();
    }

    @RequestMapping(value = "/{coworkerId}", method = RequestMethod.GET)
    public ResponseEntity<?> coworker(@PathVariable("coworkerId") int id) {
        Coworker c = repository.findOne(CoworkerRepository.PREFIX + id);
        if (c == null)
            return ResponseEntity.notFound().build();
        else
            return ResponseEntity.ok(c);
    }

    @RequestMapping(value = "/", method = RequestMethod.POST)
    public ResponseEntity<?> createCoworker(@RequestBody Map<String, Object> body) {
        String name;
        String description;
        String team;
        Set<String> skills = new HashSet<>();
        Map<String, String> imHandles;
        Location mainLocation;
        try {
            if (body.containsKey("skills")) {
                skills.addAll((Collection<String>) body.get("skills"));
            }

            imHandles = (Map<String, String>) body.get("imHandles");

            Map<String, Object> mainLocationMap = (Map<String, Object>) body.get("mainLocation");
            Map<String, Object> mainLocationCoord = (Map<String, Object>) mainLocationMap.get("coordinates");
            double x = ((Number) mainLocationCoord.get("x")).doubleValue();
            double y = ((Number) mainLocationCoord.get("y")).doubleValue();
            mainLocation = new Location((String) mainLocationMap.get("name"),
                    (String) mainLocationMap.get("description"), (int) mainLocationMap.get("timeZoneOffset"),
                    new Point(x, y));

            name = (String) body.get("name");
            description = (String) body.get("description");
            team = (String) body.get("team");

        } catch (Exception e) {
            return ResponseEntity.badRequest().body("Malformed Coworker creation data, error: " + e.toString());
        }

        //generate an ID
        Long sequence = bucket.counter("coworkerSequence", 1, TrombinoscopeApplication.RESERVED_IDS + 1).content();
        String id = CoworkerRepository.PREFIX + sequence.longValue();

        Coworker coworker = new Coworker(id, name, description, team, skills, imHandles, mainLocation, null);

        repository.save(coworker);

        final URI location = ServletUriComponentsBuilder.fromCurrentServletMapping().path("/{id}").build()
                .expand(id).toUri();

        return ResponseEntity.created(location).body(coworker);
    }

    @RequestMapping(value = "/{coworkerId}", method = RequestMethod.PUT)
    public ResponseEntity<?> updateCoworker(@PathVariable("coworkerId") int id, @RequestBody Coworker body) {
        String fullId = CoworkerRepository.PREFIX + id;
        if (!fullId.equals(body.getId())) {
            return ResponseEntity.badRequest().body(body);
        }
        if (!bucket.exists(fullId)) {
            return ResponseEntity.notFound().build();
        }
        repository.save(body);
        return ResponseEntity.ok(body);
    }

    @RequestMapping(value = "/{coworkerId}", method = RequestMethod.PATCH)
    public ResponseEntity<?> patchCoworker(@PathVariable("coworkerId") int id,
            @RequestBody Map<String, Object> body) {
        String fullId = CoworkerRepository.PREFIX + id;
        if (!bucket.exists(fullId)) {
            return ResponseEntity.notFound().build();
        }

        MutateInBuilder builder = bucket.mutateIn(fullId);

        if (body.containsKey("name")) {
            builder.upsert("name", body.get("name"), false);
        }

        if (body.containsKey("description")) {
            builder.upsert("description", body.get("description"), false);
        }

        if (body.containsKey("team")) {
            builder.upsert("team", body.get("team"), false);
        }

        if (body.containsKey("skills")) {
            Iterable<Object> skills = (Iterable<Object>) body.get("skills");
            for (Object skill : skills) {
                builder.arrayAddUnique("skills", skill, false);
            }
        }

        if (body.containsKey("imHandles")) {
            Map<String, Object> imHandles = (Map<String, Object>) body.get("imHandles");
            for (Map.Entry<String, Object> entry : imHandles.entrySet()) {
                builder.upsert("imHandles." + entry.getKey(), entry.getValue(), true);
            }
        }

        if (body.containsKey("mainLocation")) {
            Map<String, Object> mainLocation = (Map<String, Object>) body.get("mainLocation");
            if (mainLocation.containsKey("name")) {
                builder.replace("mainLocation.name", mainLocation.get("name"));
            }
            if (mainLocation.containsKey("description")) {
                builder.replace("mainLocation.description", mainLocation.get("description"));
            }

            //disallow anything else (coordinates and timezone)
            if (!mainLocation.containsKey("name") && !mainLocation.containsKey("description")) {
                return ResponseEntity.badRequest().body("Main location can only have name and description updated, "
                        + "use a different API to switch to a whole new location");
            }
        }

        if (body.containsKey("lastCheckin")) {
            return ResponseEntity.badRequest().body("Checkin can only be performed through the dedicated API");
        }

        builder.execute();
        Coworker result = repository.findOne(fullId);
        return ResponseEntity.ok().body(result);
    }

    @RequestMapping(value = "/{coworkerId}", method = RequestMethod.DELETE)
    public ResponseEntity deleteCoworker(@PathVariable("coworkerId") int id) {
        String fullId = CoworkerRepository.PREFIX + id;
        repository.delete(fullId);
        return ResponseEntity.accepted().build();
    }

}