DiversityTreeService.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.genesys.server.service;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import com.fasterxml.jackson.annotation.JsonUnwrapped;
import org.genesys.filerepository.InvalidRepositoryFileDataException;
import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.model.RepositoryFile;
import org.genesys.server.api.FilteredPage;
import org.genesys.server.exception.NotFoundElement;
import org.genesys.server.model.genesys.Accession;
import org.genesys.server.model.impl.DiversityTree;
import org.genesys.server.model.impl.DiversityTreeAccessionRef;
import org.genesys.server.model.impl.DiversityTreeCreator;
import org.genesys.server.service.filter.DiversityTreeFilter;
import org.genesys.server.exception.SearchException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author Maxym Borodenko
 */
public interface DiversityTreeService {

	/**
	 * List published records matching the filter.
	 *
	 * @param filter filter data
	 * @param page Pageable
	 * @return list of DiversityTree
	 */
	Page<DiversityTree> list(DiversityTreeFilter filter, Pageable page) throws SearchException;

	/**
	 * Count published records.
	 *
	 * @param filter the filter
	 * @return the number of published records
	 */
	long count(DiversityTreeFilter filter) throws SearchException;

	/**
	 * List current user's trees matching the filter.
	 *
	 * @param filter filter data
	 * @param page Pageable
	 * @return list of DiversityTreeFilter
	 */
	Page<DiversityTree> listForCurrentUser(DiversityTreeFilter filter, Pageable page);

	/**
	 * Create new record.
	 *
	 * @param source the source
	 * @return saved DiversityTree in db.
	 */
	DiversityTree create(@Valid DiversityTree source);

	/**
	 * Method updating tree.
	 *
	 * @param source the source
	 * @return updated tree.
	 */
	DiversityTree update(@Valid DiversityTree source);

	/**
	 * Get lazy loaded DiversityTree.
	 *
	 * @param uuid the uuid
	 * @return the tree
	 */
	DiversityTree load(UUID uuid);

	/**
	 * Get DiversityTree.
	 *
	 * @param uuid the uuid
	 * @return the tree
	 */
	DiversityTree get(UUID uuid);

	/**
	 * Get DiversityTree.
	 *
	 * @param uuid the uuid
	 * @param version the version
	 * @return the tree
	 */
	DiversityTree get(UUID uuid, int version);

	/**
	 * Get terms by filter.
	 * @param filter the filter
	 *
	 * @return the term result
	 * @throws SearchException the search exception
	 * @throws IOException the IO exception
	 */
	Map<String, ElasticsearchService.TermResult> getSuggestions(DiversityTreeFilter filter) throws SearchException, IOException;

	/**
	 * Remove record.
	 *
	 * @param input the input
	 * @return removed record
	 */
	DiversityTree remove(DiversityTree input);

	/**
	 * Load AccessionRef list by DiversityTree.
	 *
	 * @param input the input
	 * @param page Pageable
	 * @return PageImpl of AccessionRef
	 */
	Page<DiversityTreeAccessionRef> listAccessionRefs(DiversityTree input, Pageable page);

	/**
	 * Load AccessionRefs by UUIDs of trees and nodeKey
	 *
	 * @param treeUuids the UUIDs of divTrees
	 * @param nodeKey the nodeKey of accessionRef
	 * @return collection of accessionRefs
	 */
	Set<DiversityTreeAccessionRef> loadAccessionRefs(Set<UUID> treeUuids, String nodeKey);

	/**
	 * Add new accessionRefs to DiversityTree.
	 *
	 * @param input current DiversityTree
	 * @param accessionRefs the accession refs
	 * @return updated DiversityTree in db.
	 */
	DiversityTree addAccessionRefs(DiversityTree input, @Valid Collection<DiversityTreeAccessionRef> accessionRefs);

	/**
	 * Sets the accessions.
	 *
	 * @param input the input
	 * @param accessionRefs the accessions refs
	 * @return the DiversityTree
	 */
	DiversityTree setAccessionRefs(DiversityTree input, @Valid Collection<DiversityTreeAccessionRef> accessionRefs);

	/**
	 * Clear accession references across all DiversityTrees for specified accessions.
	 *
	 * @param accessions the accessions
	 * @return the int
	 */
	int clearAccessionRefs(Collection<Accession> accessions);

	/**
	 * Validates and publishes an unpublished record.
	 *
	 * @param input the input
	 * @return published record
	 */
	DiversityTree approve(DiversityTree input);

	/**
	 * Un-publishes published tree.
	 *
	 * @param input the input
	 * @return unpublished record
	 */
	DiversityTree reject(DiversityTree input);

	/**
	 * Load list of records by accession.
	 *
	 * @param accession the accession
	 * @return the loaded list
	 */
	List<DiversityTree> listByAccession(Accession accession);

	/**
	 * Create new DiversityTreeCreator.
	 *
	 * @param input the DiversityTreeCreator
	 * @param source the DiversityTreeCreator
	 * @return created DiversityTreeCreator
	 * @throws NotFoundElement throws if the not found element
	 */
	DiversityTreeCreator createCreator(DiversityTree input, @Valid DiversityTreeCreator source) throws NotFoundElement;

	/**
	 * Update creator.
	 *
	 * @param input the DiversityTree
	 * @param source the DiversityTreeCreator
	 * @return updated record
	 * @throws NotFoundElement throws if the not found element
	 */
	DiversityTreeCreator updateCreator(DiversityTree input, @Valid DiversityTreeCreator source) throws NotFoundElement;

	/**
	 * Remove new DiversityTreeCreator.
	 *
	 * @param tree the DiversityTree
	 * @param input the DiversityTreeCreator
	 * @return removed DiversityTreeCreator
	 * @throws NotFoundElement throws if the not found element
	 */
	DiversityTreeCreator removeCreator(DiversityTree tree, DiversityTreeCreator input) throws NotFoundElement;

	/**
	 * Load list creators by DiversityTree UUID.
	 *
	 * @param treeUuid the UUID
	 * @param page Page
	 * @return Page with DiversityTreeCreator list
	 */
	Page<DiversityTreeCreator> listCreators(UUID treeUuid, Pageable page);

	/**
	 * Load DiversityTreeCreator.
	 *
	 * @param input the  DiversityTreeCreator
	 * @return loaded DiversityTreeCreator
	 * @throws NotFoundElement throws if the not found element
	 */
	DiversityTreeCreator loadCreator(DiversityTreeCreator input) throws NotFoundElement;

	/**
	 * Load DiversityTreeCreator by UUID.
	 *
	 * @param uuid the uuid of creator
	 * @return loaded DiversityTreeCreator
	 * @throws NotFoundElement throws if the not found element
	 */
	DiversityTreeCreator loadCreator(UUID uuid) throws NotFoundElement;

	/**
	 * Load DiversityTreeCreator by UUID and version.
	 *
	 * @param uuid the uuid of creator
	 * @param version the version of creator
	 * @return loaded DiversityTreeCreator
	 * @throws NotFoundElement throws if the not found element
	 */
	DiversityTreeCreator loadCreator(UUID uuid, int version) throws NotFoundElement;

	/**
	 * Load list of creators by DiversityTree.
	 *
	 * @param input the DiversityTree
	 * @return List of DiversityTreeCreator
	 * @throws NotFoundElement throws if the not found element
	 */
	List<DiversityTreeCreator> loadCreators(DiversityTree input) throws NotFoundElement;

	/**
	 * Autocomplete creators.
	 *
	 * @param term the term
	 * @return list of matched creators
	 */
	List<DiversityTreeCreator> autocompleteCreators(String term);

	/**
	 * Rematch accessions across all DiversityTrees.
	 */
	void rematchAccessions();

	/**
	 * Rematch accessions for a DiversityTree
	 *
	 * @param input the DiversityTree
	 * @return the DiversityTree
	 */
	DiversityTree rematchAccessions(DiversityTree input);

//	/**
//	 * Generate Excel file with MCPD passport data for provided subset.
//	 *
//	 * @param subset the subset
//	 * @param outputStream the stream
//	 */
//	void writeXlsxMCPD(Subset subset, OutputStream outputStream) throws IOException;

	/**
	 * Method creating a new version of DiversityTree based on an existing published DiversityTree.
	 *
	 * @param source the source
	 * @return saved DiversityTree in db.
	 */
	DiversityTree createNewVersion(@Valid DiversityTree source);

	/**
	 * Upload JSON file to the repository and add it to the DiversityTree
	 *
	 * @param input the divTree entity
	 * @param file the file to be uploaded
	 * @param metadata the file metadata
	 * @return updated tree
	 */
	DiversityTree uploadFile(@NotNull DiversityTree input, @NotNull MultipartFile file, RepositoryFile metadata) throws IOException, InvalidRepositoryPathException, InvalidRepositoryFileDataException;

	public static class DiversityTreeSuggestionPage {
		@JsonUnwrapped
		public FilteredPage<DiversityTree, DiversityTreeFilter> page;
		public Map<String, ElasticsearchService.TermResult> suggestions;

		public static DiversityTreeSuggestionPage from(FilteredPage<DiversityTree, DiversityTreeFilter> page, Map<String, ElasticsearchService.TermResult> suggestions) {
			DiversityTreeSuggestionPage res = new DiversityTreeSuggestionPage();
			res.page = page;
			res.suggestions = suggestions;

			return res;
		}
	}
}