Merge branch 'release/5.0.0'
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / DescriptiveDataSetService.java
1 package eu.etaxonomy.cdm.api.service;
2
3 import java.io.Serializable;
4 import java.util.ArrayList;
5 import java.util.Arrays;
6 import java.util.Collection;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.Set;
10 import java.util.UUID;
11
12 import org.apache.log4j.Logger;
13 import org.springframework.beans.factory.annotation.Autowired;
14 import org.springframework.stereotype.Service;
15 import org.springframework.transaction.annotation.Transactional;
16
17 import eu.etaxonomy.cdm.api.service.dto.RowWrapperDTO;
18 import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
19 import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
20 import eu.etaxonomy.cdm.common.monitor.RemotingProgressMonitorThread;
21 import eu.etaxonomy.cdm.filter.TaxonNodeFilter;
22 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
23 import eu.etaxonomy.cdm.model.description.DescriptionBase;
24 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
25 import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
26 import eu.etaxonomy.cdm.model.description.DescriptiveSystemRole;
27 import eu.etaxonomy.cdm.model.description.Feature;
28 import eu.etaxonomy.cdm.model.location.NamedArea;
29 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
30 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
31 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
32 import eu.etaxonomy.cdm.model.taxon.Taxon;
33 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
34 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
35 import eu.etaxonomy.cdm.persistence.dao.description.IDescriptiveDataSetDao;
36 import eu.etaxonomy.cdm.persistence.dto.SpecimenNodeWrapper;
37 import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
38 import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
39
40 @Service
41 @Transactional(readOnly = false)
42 public class DescriptiveDataSetService
43 extends IdentifiableServiceBase<DescriptiveDataSet, IDescriptiveDataSetDao>
44 implements IDescriptiveDataSetService {
45
46 private static Logger logger = Logger.getLogger(DescriptiveDataSetService.class);
47
48 @Autowired
49 private IOccurrenceService occurrenceService;
50
51 @Autowired
52 private ITaxonNodeService taxonNodeService;
53
54 @Autowired
55 private IProgressMonitorService progressMonitorService;
56
57 @Override
58 @Autowired
59 protected void setDao(IDescriptiveDataSetDao dao) {
60 this.dao = dao;
61 }
62
63 @Override
64 public Map<DescriptionBase, Set<DescriptionElementBase>> getDescriptionElements(DescriptiveDataSet descriptiveDataSet, Set<Feature> features, Integer pageSize, Integer pageNumber,
65 List<String> propertyPaths) {
66 return dao.getDescriptionElements(descriptiveDataSet, features, pageSize, pageNumber, propertyPaths);
67 }
68
69 @Override
70 public <T extends DescriptionElementBase> Map<UuidAndTitleCache, Map<UUID, Set<T>>> getTaxonFeatureDescriptionElementMap(
71 Class<T> clazz, UUID descriptiveDataSetUuid, DescriptiveSystemRole role) {
72 return dao.getTaxonFeatureDescriptionElementMap(clazz, descriptiveDataSetUuid, role);
73 }
74
75 @Override
76 public List<UuidAndTitleCache<DescriptiveDataSet>> getDescriptiveDataSetUuidAndTitleCache(Integer limitOfInitialElements, String pattern) {
77 return dao.getDescriptiveDataSetUuidAndTitleCache( limitOfInitialElements, pattern);
78 }
79
80
81 @Override
82 @Transactional
83 public UUID monitGetRowWrapper(DescriptiveDataSet descriptiveDataSet) {
84 RemotingProgressMonitorThread monitorThread = new RemotingProgressMonitorThread() {
85 @Override
86 public Serializable doRun(IRemotingProgressMonitor monitor) {
87 return getRowWrapper(descriptiveDataSet, monitor);
88 }
89 };
90 UUID uuid = progressMonitorService.registerNewRemotingMonitor(monitorThread);
91 monitorThread.setPriority(3);
92 monitorThread.start();
93 return uuid;
94 }
95
96 @Override
97 public ArrayList<RowWrapperDTO> getRowWrapper(DescriptiveDataSet descriptiveDataSet, IProgressMonitor monitor) {
98 monitor.beginTask("Load row wrapper", descriptiveDataSet.getDescriptions().size());
99 ArrayList<RowWrapperDTO> wrappers = new ArrayList<>();
100 Set<DescriptionBase> descriptions = descriptiveDataSet.getDescriptions();
101 for (DescriptionBase description : descriptions) {
102 if(monitor.isCanceled()){
103 return new ArrayList<>();
104 }
105 wrappers.add(createRowWrapper(null, description, null, descriptiveDataSet));
106 monitor.worked(1);
107 }
108 return wrappers;
109 }
110
111 @Override
112 public Collection<SpecimenNodeWrapper> loadSpecimens(DescriptiveDataSet descriptiveDataSet){
113 //set filter parameters
114 TaxonNodeFilter filter = TaxonNodeFilter.NewRankInstance(descriptiveDataSet.getMinRank(), descriptiveDataSet.getMaxRank());
115 descriptiveDataSet.getGeoFilter().forEach(area -> filter.orArea(area.getUuid()));
116 descriptiveDataSet.getTaxonSubtreeFilter().forEach(node -> filter.orSubtree(node));
117 filter.setIncludeUnpublished(true);
118
119 List<UUID> filteredNodes = taxonNodeService.uuidList(filter);
120 return occurrenceService.listUuidAndTitleCacheByAssociatedTaxon(filteredNodes, null, null);
121 }
122
123 @Override
124 public RowWrapperDTO createRowWrapper(DescriptionBase description, DescriptiveDataSet descriptiveDataSet){
125 return createRowWrapper(null, description, null, descriptiveDataSet);
126 }
127
128 @Override
129 public RowWrapperDTO createRowWrapper(SpecimenOrObservationBase specimen, DescriptiveDataSet descriptiveDataSet){
130 return createRowWrapper(specimen, null, null, descriptiveDataSet);
131 }
132
133 private RowWrapperDTO createRowWrapper(SpecimenOrObservationBase specimen, DescriptionBase description, TaxonNode taxonNode, DescriptiveDataSet descriptiveDataSet){
134 if(description!=null){
135 specimen = description.getDescribedSpecimenOrObservation();
136 }
137 FieldUnit fieldUnit = null;
138 String identifier = null;
139 NamedArea country = null;
140 //supplemental information
141 if(specimen!=null){
142 if(taxonNode==null){
143 Collection<TaxonBase<?>> associatedTaxa = occurrenceService.listAssociatedTaxa(specimen, null, null, null,
144 Arrays.asList(new String[]{
145 "taxonNodes",
146 "taxonNodes.classification",
147 }));
148 if(associatedTaxa!=null){
149 //FIXME: what about multiple associated taxa
150 Set<TaxonNode> taxonSubtreeFilter = descriptiveDataSet.getTaxonSubtreeFilter();
151 if(taxonSubtreeFilter!=null && !taxonSubtreeFilter.isEmpty()){
152 Taxon taxon = HibernateProxyHelper.deproxy(associatedTaxa.iterator().next(), Taxon.class);
153 taxonNode = taxon.getTaxonNode(taxonSubtreeFilter.iterator().next().getClassification());
154 }
155 }
156 }
157 Collection<FieldUnit> fieldUnits = occurrenceService.getFieldUnits(specimen.getUuid(),
158 Arrays.asList(new String[]{
159 "gatheringEvent",
160 "gatheringEvent.country"
161 }));
162 if(fieldUnits.size()!=1){
163 logger.error("More than one or no field unit found for specimen"); //$NON-NLS-1$
164 }
165 else{
166 fieldUnit = fieldUnits.iterator().next();
167 }
168 if(specimen instanceof DerivedUnit){
169 identifier = occurrenceService.getMostSignificantIdentifier(HibernateProxyHelper.deproxy(specimen, DerivedUnit.class));
170 }
171 if(fieldUnit!=null && fieldUnit.getGatheringEvent()!=null){
172 country = fieldUnit.getGatheringEvent().getCountry();
173 }
174 }
175 return new RowWrapperDTO(description, specimen, taxonNode, fieldUnit, identifier, country);
176 }
177
178 @Override
179 @Transactional(readOnly = false)
180 public void updateTitleCache(Class<? extends DescriptiveDataSet> clazz, Integer stepSize,
181 IIdentifiableEntityCacheStrategy<DescriptiveDataSet> cacheStrategy, IProgressMonitor monitor) {
182 if (clazz == null) {
183 clazz = DescriptiveDataSet.class;
184 }
185 super.updateTitleCacheImpl(clazz, stepSize, cacheStrategy, monitor);
186 }
187
188 }