package org.nextprot.api.core.service.impl;
import com.google.common.collect.ImmutableList;
import org.nextprot.api.core.dao.FamilyDao;
import org.nextprot.api.core.domain.Family;
import org.nextprot.api.core.service.FamilyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.util.*;
@Lazy
@Service
class FamilyServiceImpl implements FamilyService {
private static final Map<String, Integer> REGION_SORT_INDEX = new HashMap<>();
static {
// "In the N-terminal section" < "In the C-terminal section" < "In the central section"
REGION_SORT_INDEX.put("In the N-terminal section", 0);
REGION_SORT_INDEX.put("In the central section", 1);
REGION_SORT_INDEX.put("In the C-terminal section", 2);
}
private static final Comparator<Family> FAMILY_COMPARATOR = new Comparator<Family>() {
@Override
public int compare(Family f1, Family f2) {
if (f1.getRegion() != null && f2.getRegion() != null)
return Integer.compare(REGION_SORT_INDEX.get(f1.getRegion()), REGION_SORT_INDEX.get(f2.getRegion()));
return 0;
}
};
@Autowired private FamilyDao familyDao;
@Override
@Cacheable("families")
public List<Family> findFamilies(String uniqueName) {
List<Family> families = familyDao.findFamilies(uniqueName);
for (Family child: families) {
while (true) {
Long childId = child.getFamilyId();
Family parent = familyDao.findParentOfFamilyId(childId); //TODO can this be done with one query???
if (parent==null) break;
child.setParent(parent);
child = parent; //TODO setting a reference inside a for loop????
}
}
Collections.sort(families, FAMILY_COMPARATOR);
//returns a immutable list when the result is cacheable (this prevents modifying the cache, since the cache returns a reference) copy on read and copy on write is too much time consuming
return new ImmutableList.Builder<Family>().addAll(families).build();
}
}