CropService.java

/*
 * Copyright 2018 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.genesys.server.service;

import java.io.Serializable;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;

import org.genesys.blocks.model.JsonViews;
import org.genesys.blocks.security.SecurityContextUtil;
import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.model.ImageGallery;
import org.genesys.filerepository.model.RepositoryFile;
import org.genesys.filerepository.model.RepositoryFolder;
import org.genesys.server.model.dataset.Dataset;
import org.genesys.server.model.impl.Article;
import org.genesys.server.model.impl.Crop;
import org.genesys.server.model.impl.CropLang;
import org.genesys.server.model.impl.DiversityTree;
import org.genesys.server.model.impl.Subset;
import org.genesys.server.model.traits.DescriptorList;
import org.genesys.server.service.filter.CropFilter;

import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.annotation.JsonView;

public interface CropService extends FilteredTranslatedCRUDService<
	Crop, CropLang, CropTranslationService.TranslatedCrop, CropFilter> {

	Crop getCrop(String shortName);

	CropDetails getDetails(String shortName, Locale locale) throws InvalidRepositoryPathException;

	List<CropDetails> listDetails(Locale locale);

	List<Crop> listCrops();

	List<Crop> list(Locale locale);

	Article updateBlurb(Crop crop, String title, String summary, String textBody, Locale locale) throws CRMException;

	/**
	 * Add a {@link Crop} to the system
	 * 
	 * @param shortName
	 * @param name
	 * @param description
	 * @return
	 */
	Crop addCrop(String shortName, String name, String description);

	/**
	 * Updates a crop record
	 * 
	 * @param shortName
	 * @param name
	 * @param description
	 * @return
	 */
	Crop updateCrop(Crop crop, String name, String description);

	/**
	 * Get crops
	 */
	List<Crop> getCrops(List<String> cropNames);

	/**
	 * Update crop aliases
	 * 
	 * @param crop
	 * @param otherNames
	 * @return updated crop
	 */
	Crop updateAliases(Crop crop, List<String> otherNames);

	/**
	 * Unlink accessions from crop where accession#cropName doesn't match
	 * 
	 * @param crop
	 */
	void unlinkAccessionsForCrop(Crop crop);
	
	/**
	 * Link accessions to Crop by accession#cropName
	 * 
	 * @param crop
	 */
	void linkAccessionsWithCrop(Crop crop);
	
	
	public static class CropDetails implements Serializable {
		private static final long serialVersionUID = 1622015024393351713L;

		@JsonUnwrapped
		public CropTranslationService.TranslatedCrop crop;

		@JsonView({ JsonViews.Public.class })
		public ArticleTranslationService.TranslatedArticle blurb;
		public Long accessionCount;
		public ImageGallery imageGallery; // gallery at /crop/{cropName}/covers
		public List<RepositoryFile> files; // list of files in /crop/{cropName}
		public List<Subset> recentSubsets;
		public List<Dataset> recentDatasets;
		public List<DescriptorList> recentDescriptorLists;
		public List<DiversityTree> diversityTrees;

		@JsonView({ JsonViews.Public.class })
		public Map<String, ElasticsearchService.TermResult> overview;

		public static CropDetails from(CropTranslationService.TranslatedCrop crop, ArticleTranslationService.TranslatedArticle blurb, Long accessionCount, ImageGallery imageGallery, RepositoryFolder folder, Map<String, ElasticsearchService.TermResult> overview, List<Subset> recentSubsets, List<Dataset> recentDatasets, List<DescriptorList> recentDescriptorLists) {
			CropDetails cropDetails = new CropDetails();
			cropDetails.crop = crop;
			cropDetails.blurb = blurb;
			cropDetails.accessionCount = accessionCount;
			if (folder != null) {
				folder.getFiles().size();
				// We only provide publicly accessible files
				cropDetails.files = folder.getFiles().stream().filter(file -> SecurityContextUtil.anyoneHasPermission(file, "READ")).collect(Collectors.toList());
			}
			cropDetails.imageGallery = imageGallery;
			cropDetails.overview = overview;
			cropDetails.recentDatasets = recentDatasets;
			cropDetails.recentDescriptorLists = recentDescriptorLists;
			cropDetails.recentSubsets = recentSubsets;

			return cropDetails;
		}

		public static class Builder {
			CropDetails details = new CropDetails();

			public Builder(CropTranslationService.TranslatedCrop crop) {
				details.crop = crop;
			}

			public Builder blurb(ArticleTranslationService.TranslatedArticle blurb) {
				this.details.blurb = blurb;
				return this;
			}

			public Builder accessionCount(Long accessionCount) {
				this.details.accessionCount = accessionCount;
				return this;
			}

			public Builder imageGallery(ImageGallery imageGallery) {
				this.details.imageGallery = imageGallery;
				return this;
			}

			public Builder folder(RepositoryFolder folder) {
				if (folder != null) {
					folder.getFiles().size();
					// We only provide publicly accessible files
					this.details.files = folder.getFiles().stream().filter(file -> SecurityContextUtil.anyoneHasPermission(file, "READ")).collect(Collectors.toList());
				}
				return this;
			}

			public Builder overview(Map<String, ElasticsearchService.TermResult> overview) {
				this.details.overview = overview;
				return this;
			}

			public Builder recentSubsets(List<Subset> recentSubsets) {
				this.details.recentSubsets = recentSubsets;
				return this;
			}

			public Builder recentDatasets(List<Dataset> recentDatasets) {
				this.details.recentDatasets = recentDatasets;
				return this;
			}

			public Builder recentDescriptorLists(List<DescriptorList> recentDescriptorLists) {
				this.details.recentDescriptorLists = recentDescriptorLists;
				return this;
			}

			public Builder diversityTrees(List<DiversityTree> diversityTrees) {
				this.details.diversityTrees = diversityTrees;
				return this;
			}

			public CropDetails build() {
				return this.details;
			}

		}
	}


}