Commit 436d2014 authored by Matija Obreza's avatar Matija Obreza

Split out RestController, CropController from TraitsController

parent 24144e07
# Genesys PGR - Gateway to genetic resources
## Running with Maven
```sh
$ mvn jetty:run
```
......@@ -51,4 +51,6 @@ public interface CropService {
CropRule addCropRule(Crop crop, String genus, String species, boolean included);
List<CropRule> getCropRules(Crop crop);
}
......@@ -236,4 +236,9 @@ public class CropServiceImpl implements CropService {
cropRuleRepository.save(rule);
return rule;
}
@Override
public List<CropRule> getCropRules(Crop crop) {
return crop==null ? null : cropRuleRepository.findByCrop(crop);
}
}
/**
* Copyright 2013 Global Crop Diversity Trust
*
* 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 org.genesys2.server.servlet.controller.rest;
import java.util.List;
import javax.xml.bind.ValidationException;
import net.sf.oval.ConstraintViolation;
import net.sf.oval.Validator;
import net.sf.oval.constraint.NotBlank;
import org.genesys2.server.exception.AuthorizationException;
import org.genesys2.server.model.genesys.Parameter;
import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.CropRule;
import org.genesys2.server.model.impl.CropTaxonomy;
import org.genesys2.server.service.CropService;
import org.genesys2.server.service.GenesysService;
import org.genesys2.server.service.TraitService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
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.ResponseBody;
@Controller
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = { "/api/v0", "/json/v0" })
public class CropsController extends RestController {
@Autowired
GenesysService genesysService;
@Autowired
TraitService traitService;
@Autowired
CropService cropService;
/**
* List all crops
*
* @return
* @throws AuthorizationException
*/
@RequestMapping(value = "/crops", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object listCrops() throws AuthorizationException {
LOG.info("Listing crops");
List<Crop> crops = cropService.list(LocaleContextHolder.getLocale());
return OAuth2Cleanup.clean(crops);
}
/**
* Add a crop
*
* @return
* @throws ValidationException
*/
@RequestMapping(value = "/crops", method = RequestMethod.PUT, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object createCrop(@RequestBody CropJson cropJson) throws ValidationException {
LOG.info("Creating crop");
Validator validator = new Validator();
List<ConstraintViolation> violations = validator.validate(cropJson);
if (violations.size() > 0) {
// TODO We could do better messages on validation error
throw new ModelValidationException("Crop does not validate", violations);
}
Crop crop = cropService.addCrop(cropJson.shortName, cropJson.name, cropJson.description, cropJson.i18n);
for (CropTaxonomyJson ctj : cropJson.taxonomies) {
CropRule cropRule = cropService.addCropRule(crop, ctj.genus, ctj.species, ctj.included);
if (cropRule != null)
LOG.info("Added rule: " + cropRule);
}
return crop;
}
/**
* Get crop details /crops/{shortName}
*
* @return
* @throws AuthorizationException
*/
@RequestMapping(value = "/crops/{shortName}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object getCrop(@PathVariable("shortName") String shortName) throws AuthorizationException {
LOG.info("Getting crop " + shortName);
return OAuth2Cleanup.clean(cropService.getCrop(shortName));
}
/**
* Get crop descriptors /crops/{shortName}/descriptors
*
* @return
* @throws AuthorizationException
*/
@RequestMapping(value = "/crops/{shortName}/descriptors", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object getCropDescriptors(@PathVariable("shortName") String shortName) throws AuthorizationException {
LOG.info("Getting crop descriptors " + shortName);
Crop crop = cropService.getCrop(shortName);
Page<Parameter> descriptors = traitService.listTraits(crop, new PageRequest(0, 50));
return OAuth2Cleanup.clean(descriptors);
}
/**
* Get crop taxonomy rules /crops/{shortName}/rules
*
* @return
* @throws AuthorizationException
*/
@RequestMapping(value = "/crops/{shortName}/rules", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object getCropRules(@PathVariable("shortName") String shortName) throws AuthorizationException {
LOG.info("Getting crop rules " + shortName);
Crop crop = cropService.getCrop(shortName);
List<CropRule> cropRules = cropService.getCropRules(crop);
return OAuth2Cleanup.clean(cropRules);
}
/**
* Get crop taxonomies /crops/{shortName}/taxa
*
* @return
* @throws AuthorizationException
*/
@RequestMapping(value = "/crops/{shortName}/taxa", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object getCropTaxa(@PathVariable("shortName") String shortName) throws AuthorizationException {
LOG.info("Getting crop taxa " + shortName);
Crop crop = cropService.getCrop(shortName);
Page<CropTaxonomy> cropTaxa = cropService.getCropTaxonomies(crop, new PageRequest(0, 50));
return OAuth2Cleanup.clean(cropTaxa);
}
public static class CropJson {
@NotBlank
public String shortName;
public String name;
public String description;
public String i18n;
public List<CropTaxonomyJson> taxonomies;
}
public static class CropTaxonomyJson {
@NotBlank
public String genus;
public String species;
public boolean included;
}
}
\ No newline at end of file
......@@ -14,12 +14,15 @@
* limitations under the License.
**/
package org.genesys2.server.servlet.controller.rest;
import java.util.Collection;
import org.genesys2.server.model.genesys.Method;
import org.genesys2.server.model.genesys.Parameter;
import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.CropRule;
import org.genesys2.server.model.impl.CropTaxonomy;
import org.genesys2.server.model.impl.User;
import org.springframework.data.domain.Page;
......@@ -43,9 +46,25 @@ public class OAuth2Cleanup {
Crop crop = (Crop) t;
crop.setCropRules(null);
}
if (t instanceof CropRule) {
CropRule cropRule = (CropRule) t;
cropRule.setCrop(null);
}
if (t instanceof CropTaxonomy) {
CropTaxonomy cropTaxa = (CropTaxonomy) t;
cropTaxa.setCrop(null);
cropTaxa.getTaxonomy().setCropTaxonomies(null);
}
return t;
}
public static <T> Collection<T> clean(Collection<T> x) {
for (T m : x) {
clean(m);
}
return x;
}
public static <T> Page<T> clean(Page<T> x) {
for (T m : x.getContent()) {
clean(m);
......
package org.genesys2.server.servlet.controller.rest;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
public class RestController {
protected final Log LOG = LogFactory.getLog(getClass());
public RestController() {
super();
}
@ExceptionHandler(Exception.class)
@ResponseBody
public ExceptionJson handleIOException(Exception ex, HttpServletRequest request, HttpServletResponse response) throws IOException {
LOG.warn("Unexpected error: " + ex.getLocalizedMessage());
return new ExceptionJson(ex);
}
}
\ No newline at end of file
......@@ -16,24 +16,9 @@
package org.genesys2.server.servlet.controller.rest;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.ValidationException;
import net.sf.oval.ConstraintViolation;
import net.sf.oval.Validator;
import net.sf.oval.constraint.NotBlank;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.genesys2.server.exception.AuthorizationException;
import org.genesys2.server.model.genesys.Method;
import org.genesys2.server.model.genesys.Parameter;
import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.CropRule;
import org.genesys2.server.service.CropService;
import org.genesys2.server.service.GenesysService;
import org.genesys2.server.service.TraitService;
......@@ -43,9 +28,7 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
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.ResponseBody;
......@@ -53,8 +36,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = { "/api/v0", "/json/v0" })
public class TraitsController {
private static final Log LOG = LogFactory.getLog(TraitsController.class);
public class TraitsController extends RestController {
@Autowired
GenesysService genesysService;
......@@ -65,42 +47,6 @@ public class TraitsController {
@Autowired
CropService cropService;
@ExceptionHandler(Exception.class)
public @ResponseBody
ExceptionJson handleIOException(Exception ex, HttpServletRequest request, HttpServletResponse response) throws IOException {
LOG.warn("Unexpected error: " + ex.getLocalizedMessage());
// response.setContentType("application/json");
// response.setStatus(400);
return new ExceptionJson(ex);
}
/**
* New descriptor
*
* @return
* @throws AuthorizationException
* @throws ValidationException
*/
@RequestMapping(value = "/crops", method = RequestMethod.PUT, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object createCrop(@RequestBody CropJson cropJson) throws ValidationException {
LOG.info("Creating crop");
Validator validator = new Validator();
List<ConstraintViolation> violations = validator.validate(cropJson);
if (violations.size() > 0) {
// TODO We could do better messages on validation error
throw new ModelValidationException("Crop does not validate", violations);
}
Crop crop = cropService.addCrop(cropJson.shortName, cropJson.name, cropJson.description, cropJson.i18n);
for (CropTaxonomyJson ctj : cropJson.taxonomies) {
CropRule cropRule = cropService.addCropRule(crop, ctj.genus, ctj.species, ctj.included);
if (cropRule != null)
LOG.info("Added rule: " + cropRule);
}
return crop;
}
@RequestMapping(value = "/descriptors", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object listTraits() throws AuthorizationException {
......@@ -133,19 +79,4 @@ public class TraitsController {
return OAuth2Cleanup.clean(methods);
}
public static class CropJson {
@NotBlank
public String shortName;
public String name;
public String description;
public String i18n;
public List<CropTaxonomyJson> taxonomies;
}
public static class CropTaxonomyJson {
@NotBlank
public String genus;
public String species;
public boolean included;
}
}
\ No newline at end of file
......@@ -20,6 +20,7 @@
<textarea class="form-control" style="height: 200px;" id="responseBody" placeholder="Response Body..."></textarea>
<button id="clearResponse">Clear</button>
<button class="json-api" x-url="/crops">List crops JSON</button>
<h2>Add Crop</h2>
<form class="json-api form-horizontal">
......
......@@ -21,6 +21,7 @@
<button class="rest-api" x-url="/me">Me!</button>
<button class="rest-api" x-url="/descriptors">List descriptors</button>
<button class="rest-api" x-url="/methods">List methods</button>
<button class="json-api" x-url="/crops">List crops JSON</button>
<button class="json-api" x-url="/methods">List methods JSON</button>
</body>
</html>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment