CropTraitObservationController.java

/*
 * Copyright 2020 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.gringlobal.api.v1.impl;

import org.apache.commons.lang3.ArrayUtils;
import org.gringlobal.api.v1.FilteredCRUDController;
import org.gringlobal.api.v1.Pagination;
import org.gringlobal.model.CropTrait;
import org.gringlobal.model.CropTraitObservation;
import org.gringlobal.model.CropTraitObservationData;
import org.gringlobal.model.Inventory;
import org.gringlobal.model.QCropTrait;
import org.gringlobal.model.QCropTraitObservation;
import org.gringlobal.model.QCropTraitObservationData;
import org.gringlobal.model.QInventory;
import org.gringlobal.service.CropTraitObservationDataService;
import org.gringlobal.service.CropTraitObservationService;
import org.gringlobal.service.filter.CropTraitObservationDataFilter;
import org.gringlobal.service.filter.CropTraitObservationFilter;
import org.gringlobal.spring.MinifyingHttpMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.querydsl.core.types.OrderSpecifier;

import org.springdoc.api.annotations.ParameterObject;
import io.swagger.v3.oas.annotations.tags.Tag;

import javax.validation.Valid;
import java.util.Set;

@RestController("cropTraitObservationApi1")
@RequestMapping(CropTraitObservationController.API_URL)
@PreAuthorize("isAuthenticated()")
@Tag(name = "CropTrait")
public class CropTraitObservationController extends FilteredCRUDController<CropTraitObservation, CropTraitObservationService, CropTraitObservationFilter> {

	/** The Constant API_URL. */
	public static final String API_URL = CropTraitController.API_URL + "/observations";

	@Autowired
	private CropTraitObservationService observationService;


	private OrderSpecifier<?>[] observationsDefaultSort() {
		return new OrderSpecifier[] { QCropTraitObservation.cropTraitObservation.inventory().id.asc() };
	}

	/**
	 * Get distinct inventories from CropTraitObservations for selected method.
	 *
	 * @param methodId the id of method
	 * @param page the page
	 * @return the page of inventories
	 */
	@GetMapping(value = "/{methodId}/inventories", produces = { MediaType.APPLICATION_JSON_VALUE })
	public Page<Inventory> getInventories(@ParameterObject final Pagination page, @PathVariable Long methodId) {

		Pageable pageable = ArrayUtils.isEmpty(page.getS()) ? page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE, QInventory.inventory.id.asc()) : page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE);
		return observationService.getObservationInventoriesByMethod(methodId, pageable);
	}

	/**
	 * Get distinct crop trait from CropTraitObservations for selected method.
	 *
	 * @param methodId the id of method
	 * @param page the page
	 * @return the page of crop traits
	 */
	@GetMapping(value = "/{methodId}/traits", produces = { MediaType.APPLICATION_JSON_VALUE })
	public Page<CropTrait> getTraits(@ParameterObject final Pagination page, @PathVariable Long methodId) {

		Pageable pageable = ArrayUtils.isEmpty(page.getS()) ? page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE, QCropTrait.cropTrait.id.asc()) : page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE);
		return observationService.getObservationTraitsByMethod(methodId, pageable);
	}

	/**
	 * Ensure CropTraitObservations for given method, inventories and traits
	 *
	 * @param request the request
	 * @return the number of created observations
	 */
	@PostMapping(value = "/ensure")
	public int ensureObservations(@RequestBody @Valid EnsureObservationsRequest request) {

		return observationService.ensureObservations(request);
	}

	public static class EnsureObservationsRequest {
		public Long methodId;
		public Set<Long> cropTraitId;
		public Set<Long> inventoryId;
	}

	@PostMapping(value = "/search", produces = { MinifyingHttpMessageConverter.APPLICATION_MINIFIED_JSON_VALUE })
	public CropTraitObservationService.FilteredObservations filterObservations(@ParameterObject final Pagination page,
			@RequestBody(required = true) final CropTraitObservationFilter filter) {

		Pageable pageable = ArrayUtils.isEmpty(page.getS()) ? page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE, observationsDefaultSort()) : page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE);
		return observationService.search(filter, pageable);
	}

	@RestController("cropTraitObservationDataApi1")
	@RequestMapping(CropTraitObservationDataController.API_URL)
	@PreAuthorize("isAuthenticated()")
	@Tag(name = "CropTrait")
	public static class CropTraitObservationDataController extends FilteredCRUDController<CropTraitObservationData, CropTraitObservationDataService, CropTraitObservationDataFilter> {
		/** The Constant API_URL. */
		public static final String API_URL = CropTraitObservationController.API_URL + "-data";

		@Autowired
		private CropTraitObservationDataService observationDataService;

		private OrderSpecifier<?>[] observationsDataDefaultSort() {
			return new OrderSpecifier[] { QCropTraitObservationData.cropTraitObservationData.inventory().id.asc() };
		}

		/**
		 * Get distinct inventories from CropTraitObservationData for selected method.
		 *
		 * @param methodId the id of method
		 * @param page the page
		 * @return the page of inventories
		 */
		@GetMapping(value = "/{methodId}/inventories", produces = { MediaType.APPLICATION_JSON_VALUE })
		public Page<Inventory> getInventories(@ParameterObject final Pagination page, @PathVariable Long methodId) {

			Pageable pageable = ArrayUtils.isEmpty(page.getS()) ? page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE, QInventory.inventory.id.asc()) : page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE);
			return observationDataService.getObservationDataInventoriesByMethod(methodId, pageable);
		}

		/**
		 * Get distinct crop trait from CropTraitObservationData for selected method.
		 *
		 * @param methodId the id of method
		 * @param page the page
		 * @return the page of crop traits
		 */
		@GetMapping(value = "/{methodId}/traits", produces = { MediaType.APPLICATION_JSON_VALUE })
		public Page<CropTrait> getTraits(@ParameterObject final Pagination page, @PathVariable Long methodId) {

			Pageable pageable = ArrayUtils.isEmpty(page.getS()) ? page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE, QCropTrait.cropTrait.id.asc()) : page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE);
			return observationDataService.getObservationDataTraitsByMethod(methodId, pageable);
		}

		/**
		 * Ensure CropTraitObservationData for given method, inventories and traits
		 *
		 * @param request the request
		 * @return the number of created observation data
		 */
		@PostMapping(value = "/ensure")
		public int ensureObservationData(@RequestBody @Valid EnsureObservationsRequest request) {

			return observationDataService.ensureObservationData(request);
		}

		@PostMapping(value = "/search", produces = { MinifyingHttpMessageConverter.APPLICATION_MINIFIED_JSON_VALUE })
			public CropTraitObservationDataService.FilteredObservationsData filterObservationsData(@ParameterObject final Pagination page,
				@RequestBody(required = true) final CropTraitObservationDataFilter filter) {

			Pageable pageable = ArrayUtils.isEmpty(page.getS()) ? page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE, observationsDataDefaultSort()) : page.toPageRequest(MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE);
			return observationDataService.search(filter, pageable);
		}

	}

}