CooperatorServiceImpl.java

/*
 * Copyright 2019 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.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.gringlobal.api.exception.InvalidApiUsageException;
import org.gringlobal.custom.elasticsearch.SearchException;
import org.gringlobal.model.Cooperator;
import org.gringlobal.model.QCooperator;
import org.gringlobal.model.community.CommunityCodeValues;
import org.gringlobal.persistence.CooperatorRepository;
import org.gringlobal.service.CooperatorService;
import org.gringlobal.service.filter.CooperatorFilter;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.querydsl.core.types.dsl.NumberPath;
import com.querydsl.jpa.impl.JPAQuery;

@Service(value = "cooperatorService")
@Transactional(readOnly = true)
@Slf4j
public class CooperatorServiceImpl extends FilteredCRUDServiceImpl<Cooperator, CooperatorFilter, CooperatorRepository> implements CooperatorService {

	private static final String[] BOOST_FIELDS = { "firstName", "lastName", "organization" };


	@Override
	public Cooperator _lazyLoad(Cooperator entity) {
		entity.lazyLoad();
		return entity;
	}

	@Override
	@Transactional
	@PreAuthorize("@ggceSec.actionAllowed('CooperatorData', 'CREATE')")
	public Cooperator create(Cooperator source) {
		log.debug("Create. Input data {}", source);
		Cooperator cooperator = new Cooperator();
		cooperator.apply(source);

		Cooperator saved = repository.save(cooperator);
		saved.lazyLoad();

		return saved;
	}

	@Override
	@Transactional
	@PreAuthorize("@ggceSec.actionAllowed('CooperatorData', 'WRITE')")
	public Cooperator update(Cooperator updated) {
		return super.update(updated);
	}

	@Override
	@Transactional
	@PreAuthorize("@ggceSec.actionAllowed('CooperatorData', 'WRITE')")
	public Cooperator update(Cooperator updated, Cooperator target) {
		log.debug("Update Cooperator. Input data {}", updated);
		target.apply(updated);

		Cooperator saved = repository.save(target);
		return _lazyLoad(saved);
	}

	@Override
	@Transactional
	@PreAuthorize("@ggceSec.actionAllowed('CooperatorData', 'CREATE') && @ggceSec.actionAllowed('CooperatorData', 'WRITE')")
	public Cooperator saveAsNew(final Cooperator updated) {
		final Cooperator original = get(updated);
		final Cooperator target = new Cooperator();

		target.apply(updated);

		// save a new cooperator
		target.setId(null);
		target.setStatusCode(CommunityCodeValues.COOPERATOR_STATUS_ACTIVE.value);
		Cooperator saved = null;
		try {
			saved = repository.save(target);
		} catch (DataIntegrityViolationException e) {
			Throwable cause = e;
			while (cause.getCause() != null && !cause.equals(cause.getCause())) {
				cause = cause.getCause();
			}
			throw new InvalidApiUsageException(cause.getMessage(), e);
		}

		// update the original cooperator
		original.setStatusCode(CommunityCodeValues.COOPERATOR_STATUS_INACTIVE.value);
		original.setCurrentCooperator(saved);
		repository.save(original);

		return _lazyLoad(saved);
	}

	@Override
	@Transactional
	@PreAuthorize("@ggceSec.actionAllowed('CooperatorData', 'DELETE')")
	public Cooperator remove(Cooperator entity) {
		return super.remove(entity);
	}

	@Override
	public Page<Cooperator> list(CooperatorFilter filter, Pageable page) throws SearchException {
		var list = super.list(Cooperator.class, filter, page, BOOST_FIELDS);
		for (Cooperator cooperator : list) {
			cooperator.getSysLang().getId();
		}
		return list;
	}

	@Override
	protected JPAQuery<Cooperator> entityListQuery() {
		return jpaQueryFactory.selectFrom(QCooperator.cooperator)
			// site
			.leftJoin(QCooperator.cooperator.site()).fetchJoin()
			// geography
			.leftJoin(QCooperator.cooperator.geography()).fetchJoin()
			// currentCooperator
			.leftJoin(QCooperator.cooperator.currentCooperator()).fetchJoin()
			// owner
			.join(QCooperator.cooperator.ownedBy()).fetchJoin();
	}

	@Override
	protected NumberPath<Long> entityIdPredicate() {
		return QCooperator.cooperator.id;
	}

	@Override
	public String getCooperatorName(long id) {
		Cooperator cooperator = repository.findById(id).orElse(null);
		if (cooperator != null) {
			String name = cooperator.getFirstName() + " " + StringUtils.defaultIfBlank(cooperator.getLastName(), "");
			return name.strip();
		}
		return null;
	}
}