View Javadoc
1   package fr.ifremer.tutti.persistence.service.referential;
2   
3   /*
4    * #%L
5    * Tutti :: Persistence
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2012 - 2014 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU General Public License as
13   * published by the Free Software Foundation, either version 3 of the
14   * License, or (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU General Public
22   * License along with this program.  If not, see
23   * <http://www.gnu.org/licenses/gpl-3.0.html>.
24   * #L%
25   */
26  
27  import com.google.common.base.Preconditions;
28  import com.google.common.collect.Lists;
29  import fr.ifremer.adagio.core.dao.referential.taxon.TaxonName;
30  import fr.ifremer.adagio.core.dao.referential.taxon.TaxonNameImpl;
31  import fr.ifremer.adagio.core.dao.referential.taxon.TaxonRefVO;
32  import fr.ifremer.adagio.core.dao.referential.transcribing.TranscribingItemType;
33  import fr.ifremer.adagio.core.dao.referential.transcribing.TranscribingItemTypeDao;
34  import fr.ifremer.adagio.core.dao.referential.transcribing.TranscribingItemTypeId;
35  import fr.ifremer.adagio.core.dao.technical.hibernate.TemporaryDataHelper;
36  import fr.ifremer.tutti.persistence.dao.TaxonNameDaoTutti;
37  import fr.ifremer.tutti.persistence.entities.referential.Species;
38  import fr.ifremer.tutti.persistence.entities.referential.Speciess;
39  import org.apache.commons.lang3.StringUtils;
40  import org.apache.commons.logging.Log;
41  import org.apache.commons.logging.LogFactory;
42  import org.hibernate.Query;
43  import org.hibernate.type.IntegerType;
44  import org.hibernate.type.StringType;
45  import org.nuiton.jaxx.application.ApplicationBusinessException;
46  import org.springframework.cache.Cache;
47  import org.springframework.dao.DataRetrievalFailureException;
48  import org.springframework.stereotype.Service;
49  
50  import javax.annotation.Resource;
51  import java.util.Collection;
52  import java.util.Collections;
53  import java.util.List;
54  import java.util.Map;
55  import java.util.TreeMap;
56  
57  /**
58   * Created on 11/3/14.
59   *
60   * @author Tony Chemit - chemit@codelutin.com
61   * @since 3.8
62   */
63  @Service("speciesPersistenceService")
64  public class SpeciesPersistenceServiceImpl extends ReferentialPersistenceServiceSupport implements SpeciesPersistenceService {
65  
66      /** Logger. */
67      private static final Log log = LogFactory.getLog(SpeciesPersistenceServiceImpl.class);
68  
69      public static final String TAXINOMIE_COMMUN_REFERENCE_HISTORY = "TAXINOMIE-COMMUN.REFERENCE_HISTORY";
70  
71      @Resource(name = "taxonNameDaoTutti")
72      protected TaxonNameDaoTutti taxonNameDao;
73  
74      @Resource(name = "transcribingItemTypeDao")
75      protected TranscribingItemTypeDao transcribingItemTypeDao;
76  
77      @Override
78      public List<Species> getAllSpecies() {
79  
80          TaxonRefVO[] sources = taxonNameDao.getAllTaxonNames(
81                  true, TranscribingItemTypeId.TAXON_NAME_REFTAX_CODE.getValue());
82  
83          List<Species> result = Lists.newArrayListWithCapacity(sources.length);
84          List<Species> referenceTaxonsOnly = Lists.newArrayList();
85          Cache referentSpeciesByIdCache = cacheService.getCache("referentSpeciesById");
86          for (TaxonRefVO source : sources) {
87              Species target = loadSpecies(source);
88  
89              // FIXME kmorin 20130423 http://forge.codelutin.com/issues/2350
90              target.setRefTaxCode(StringUtils.trim(target.getExternalCode()));
91  
92              if (target.isReferenceTaxon()) {
93  
94                  // Add to cache :
95                  referentSpeciesByIdCache.put(target.getReferenceTaxonId(), target);
96  
97                  referenceTaxonsOnly.add(target);
98              }
99              result.add(target);
100         }
101 
102         // Add to cache :
103         Cache allReferentSpeciesCache = cacheService.getCache("referentSpecies");
104         allReferentSpeciesCache.put("", referenceTaxonsOnly);
105 
106         return Collections.unmodifiableList(result);
107 
108     }
109 
110     @Override
111     public List<Species> getAllReferentSpecies() {
112 
113         TaxonRefVO[] sources = taxonNameDao.getAllTaxonNames(
114                 false, TranscribingItemTypeId.TAXON_NAME_REFTAX_CODE.getValue());
115         List<Species> result = Lists.newArrayListWithCapacity(sources.length);
116         Cache referentSpeciesByIdCache = cacheService.getCache("referentSpeciesById");
117         loadReferentSpecies(sources, result, referentSpeciesByIdCache);
118 
119         return Collections.unmodifiableList(result);
120 
121     }
122 
123     @Override
124     public List<Species> getAllReferentSpeciesWithObsoletes() {
125 
126         TaxonRefVO[] sources = taxonNameDao.getAllTaxonNamesWithObsoletes(
127                 false, TranscribingItemTypeId.TAXON_NAME_REFTAX_CODE.getValue());
128         List<Species> result = Lists.newArrayListWithCapacity(sources.length);
129 
130         loadReferentSpecies(sources, result, null);
131         return Collections.unmodifiableList(result);
132 
133     }
134 
135     protected void loadReferentSpecies(TaxonRefVO[] sources, List<Species> result, Cache referentSpeciesByIdCache) {
136         for (TaxonRefVO source : sources) {
137             Species target = loadSpecies(source);
138 
139             // FIXME kmorin 20130423 http://forge.codelutin.com/issues/2350
140             target.setRefTaxCode(StringUtils.trim(target.getExternalCode()));
141 
142             if (referentSpeciesByIdCache != null) {
143                 // Add to cache
144                 referentSpeciesByIdCache.put(target.getReferenceTaxonId(), target);
145             }
146 
147             result.add(target);
148         }
149     }
150 
151     @Override
152     public Species getSpeciesByReferenceTaxonId(Integer referenceTaxonId) {
153 
154         try {
155             Species result = getSpeciesByReferenceTaxonId(
156                     referenceTaxonId,
157                     TranscribingItemTypeId.TAXON_NAME_REFTAX_CODE.getValue());
158             if (result != null) {
159                 result.setRefTaxCode(result.getExternalCode());
160             }
161             return result;
162         } catch (Exception e) {
163             throw new CouldNotLoadTaxonException(referenceTaxonId, "Could not getSpeciesByReferenceTaxonId with referenceTaxonId: " + referenceTaxonId, e);
164         }
165     }
166 
167     @Override
168     public Species getSpeciesByReferenceTaxonIdWithVernacularCode(Integer referenceTaxonId) {
169 
170         try {
171             Species result = getSpeciesByReferenceTaxonId(
172                     referenceTaxonId,
173                     TranscribingItemTypeId.TAXON_NAME_LOCAL_NAME.getValue());
174             if (result != null) {
175                 result.setVernacularCode(result.getExternalCode());
176             }
177             return result;
178         } catch (Exception e) {
179             throw new CouldNotLoadTaxonException(referenceTaxonId, "Could not getSpeciesByReferenceTaxonId with referenceTaxonId: " + referenceTaxonId, e);
180         }
181 
182 
183     }
184 
185     @Override
186     public Map<Integer, Integer> getAllObsoleteReferentTaxons() {
187 
188         TranscribingItemType transcribingItemType = transcribingItemTypeDao.searchUniqueLabel(TAXINOMIE_COMMUN_REFERENCE_HISTORY);
189 
190         Map<Integer, Integer> result = new TreeMap<>();
191 
192         if (transcribingItemType == null) {
193 
194             if (log.isWarnEnabled()) {
195                 log.warn("Could not find transcribing item type with label: '" + TAXINOMIE_COMMUN_REFERENCE_HISTORY + "'");
196             }
197 
198         } else {
199 
200             Query query = createQuery("allTranscribingForAType", "transcribingTypeId", IntegerType.INSTANCE, transcribingItemType.getId());
201 
202             for (Object o : query.list()) {
203                 Object[] cols = (Object[]) o;
204                 Integer referencetaxonId = (Integer) cols[0];
205                 String externalCode = (String) cols[1];
206                 result.put(Integer.valueOf(externalCode), referencetaxonId);
207             }
208 
209             if (log.isInfoEnabled()) {
210                 log.info("Loaded allObsoleteReferentTaxons : " + result.size());
211             }
212 
213             if (log.isDebugEnabled()) {
214                 log.info("Loaded allObsoleteReferentTaxons : " + result.keySet());
215             }
216 
217         }
218 
219         return result;
220 
221     }
222 
223     protected Species getSpeciesByReferenceTaxonId(Integer referenceTaxonId,
224                                                    Integer transcribingTypeId) {
225 
226         Species target;
227         try {
228             TaxonRefVO source = taxonNameDao.getTaxonNameReferent(
229                     referenceTaxonId, transcribingTypeId);
230             target = loadSpecies(source);
231         } catch (DataRetrievalFailureException drfe) {
232             target = null;
233         }
234         return target;
235 
236     }
237 
238     @Override
239     public boolean isTemporarySpeciesUsed(Integer referenceTaxonId) {
240 
241         Long count = queryUniqueTyped("countReferenceTaxonInSortingBatch", "id", IntegerType.INSTANCE, referenceTaxonId);
242         boolean result = count > 0;
243 
244         if (!result) {
245             count = queryUniqueTyped("countReferenceTaxonInSample", "id", IntegerType.INSTANCE, referenceTaxonId);
246             result = count > 0;
247         }
248         return result;
249 
250     }
251 
252     @Override
253     public List<Species> addTemporarySpecies(List<Species> species) {
254 
255         List<Species> result = Lists.newArrayList();
256         for (Species source : species) {
257             Species added = addTemporarySpecies(source);
258             result.add(added);
259         }
260         return Collections.unmodifiableList(result);
261 
262     }
263 
264     @Override
265     public List<Species> updateTemporarySpecies(List<Species> species) {
266 
267         List<Species> result = Lists.newArrayList();
268         for (Species source : species) {
269             Species updated = updateTemporarySpecies(source);
270             result.add(updated);
271         }
272         return Collections.unmodifiableList(result);
273 
274     }
275 
276     @Override
277     public List<Species> linkTemporarySpecies(List<Species> species) {
278 
279         List<Species> result = Lists.newArrayList();
280         for (Species source : species) {
281             Species linked = linkTemporarySpecies(source);
282             result.add(linked);
283         }
284         return Collections.unmodifiableList(result);
285 
286     }
287 
288     @Override
289     public void replaceSpecies(Species source, Species target, boolean delete) {
290 
291         Preconditions.checkNotNull(source);
292         Preconditions.checkNotNull(target);
293         Preconditions.checkState(Speciess.isTemporary(source));
294         Preconditions.checkState(!Speciess.isTemporary(target));
295 
296         Integer sourceId = source.getReferenceTaxonId();
297         Integer targetId = target.getReferenceTaxonId();
298 
299         queryUpdate("replaceReferenceTaxonInSortingBatch",
300                 "sourceId", IntegerType.INSTANCE, sourceId,
301                 "targetId", IntegerType.INSTANCE, targetId);
302 
303         queryUpdate("replaceReferenceTaxonInSample",
304                 "sourceId", IntegerType.INSTANCE, sourceId,
305                 "targetId", IntegerType.INSTANCE, targetId);
306 
307         //TODO Check doublon...
308 
309         if (delete) {
310 
311             deleteTemporarySpecies(sourceId);
312 
313         }
314 
315     }
316 
317     @Override
318     public void deleteTemporarySpecies(Collection<Integer> referenceTaxonIds) {
319 
320         for (Integer id : referenceTaxonIds) {
321             deleteTemporarySpecies(id);
322         }
323 
324     }
325 
326     @Override
327     public void deleteTemporarySpecies(Integer referenceTaxonId) {
328 
329         Preconditions.checkNotNull(referenceTaxonId);
330         if (referenceTaxonId > 0) {
331             throw new ApplicationBusinessException(String.format("Can't delete a Species with a positive id %d.", referenceTaxonId));
332         }
333         Species species = getSpeciesByReferenceTaxonId(referenceTaxonId);
334         if (species == null) {
335             throw new ApplicationBusinessException(String.format("Species with id %d does not exists", referenceTaxonId));
336         }
337 
338         taxonNameDao.remove(species.getIdAsInt());
339 
340     }
341 
342     protected Species addTemporarySpecies(Species source) {
343 
344         Preconditions.checkNotNull(source);
345         Preconditions.checkNotNull(source.getName());
346         Preconditions.checkArgument(source.getId() == null || Speciess.isTemporaryId(source.getIdAsInt()));
347 
348         TaxonRefVO taxonRefVO = null;
349         if (source.getReferenceTaxonId() != null) {
350             taxonRefVO = taxonNameDao.getTaxonNameReferent(source.getReferenceTaxonId());
351         }
352         if (taxonRefVO == null) {
353             taxonRefVO = new TaxonRefVO();
354             taxonRefVO.setName(source.getName());
355             taxonRefVO = taxonNameDao.createAsTemporary(
356                     taxonRefVO,
357                     "Added by tutti (file import).");
358         } else {
359             TaxonName taxonName = load(TaxonNameImpl.class, taxonRefVO.getTaxonNameId());
360             taxonName.setName(source.getName());
361             taxonRefVO.setName(source.getName());
362             taxonNameDao.update(taxonName);
363         }
364 
365         // update the source
366         Species result = loadSpecies(taxonRefVO);
367         result.setRefTaxCode(result.getExternalCode());
368 
369         // Add to cache
370         Cache cache = cacheService.getCache("referentSpeciesById");
371         cache.put(result.getIdAsInt(), result);
372 
373         return result;
374 
375     }
376 
377     protected Species updateTemporarySpecies(Species source) {
378 
379         Preconditions.checkNotNull(source);
380         Preconditions.checkNotNull(source.getName());
381         Preconditions.checkNotNull(source.getId());
382         Preconditions.checkNotNull(source.getReferenceTaxonId());
383         Preconditions.checkArgument(Speciess.isTemporaryId(source.getIdAsInt()));
384 
385         TaxonRefVO taxonRefVO = taxonNameDao.getTaxonNameReferent(source.getReferenceTaxonId());
386 
387         TaxonName taxonName = load(TaxonNameImpl.class, taxonRefVO.getTaxonNameId());
388         taxonName.setName(source.getName());
389         taxonRefVO.setName(source.getName());
390         taxonNameDao.update(taxonName);
391 
392         // update the source
393         Species result = loadSpecies(taxonRefVO);
394         result.setRefTaxCode(result.getExternalCode());
395 
396         // Add to cache
397         Cache cache = cacheService.getCache("referentSpeciesById");
398         cache.put(result.getIdAsInt(), result);
399 
400         return result;
401 
402     }
403 
404     protected Species linkTemporarySpecies(Species source) {
405 
406         Preconditions.checkNotNull(source);
407         Preconditions.checkNotNull(source.getName());
408         Preconditions.checkNotNull(source.getId());
409         Preconditions.checkArgument(Speciess.isTemporaryId(source.getIdAsInt()));
410 
411         String taxonName = TemporaryDataHelper.TEMPORARY_NAME_PREFIX + source.getName();
412         Integer referenceTaxonId = queryUniqueTyped(
413                 "taxonNameReferenceTaxonIdByName",
414                 "taxonName", StringType.INSTANCE, taxonName);
415 
416         return getSpeciesByReferenceTaxonId(referenceTaxonId);
417 
418     }
419 
420     protected Species loadSpecies(TaxonRefVO source) {
421 
422         Species target = Speciess.newSpecies();
423         target.setId(source.getTaxonNameId());
424         target.setName(source.getName());
425         target.setExternalCode(source.getExternalCode());
426         target.setReferenceTaxonId(source.getReferenceTaxonId());
427         target.setReferenceTaxon(source.getIsReference());
428         setStatus(source.getStatus().getValue(), target);
429         return target;
430 
431     }
432 }