Java tutorial
/* * 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(); } }