Project

General

Profile

« Previous | Next » 

Revision 1cc6cd7b

Added by Andreas Müller almost 6 years ago

ref #6359, ref #3740 (setSubtree) add progress monitor progress computation, first version of partitioning

View differences:

cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonNodeDaoHibernateImpl.java
31 31
import org.springframework.beans.factory.annotation.Qualifier;
32 32
import org.springframework.stereotype.Repository;
33 33

  
34
import eu.etaxonomy.cdm.common.CdmUtils;
35
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
34 36
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
37
import eu.etaxonomy.cdm.model.common.CdmBase;
35 38
import eu.etaxonomy.cdm.model.common.TreeIndex;
36 39
import eu.etaxonomy.cdm.model.reference.Reference;
37 40
import eu.etaxonomy.cdm.model.taxon.Classification;
......
44 47
import eu.etaxonomy.cdm.persistence.dao.taxon.IClassificationDao;
45 48
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
46 49
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;
47
import eu.etaxonomy.cdm.persistence.dto.MergeResult;
48 50
import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
49 51
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
50 52

  
......
465 467
        return result;
466 468
    }
467 469

  
470
    /**
471
     * {@inheritDoc}
472
     */
473
    @Override
474
    public int countSecundumForSubtreeAcceptedTaxa(TreeIndex subTreeIndex, Reference newSec,
475
            boolean overwriteExisting, boolean includeSharedTaxa, boolean emptySecundumDetail) {
476
        String queryStr = acceptedForSubtreeQueryStr(includeSharedTaxa, subTreeIndex, SelectMode.COUNT);
477
        if (!overwriteExisting){
478
            queryStr += " AND t.sec IS NULL ";
479
        }
480
        return countResult(queryStr);
481

  
482
    }
483
    /**
484
     * @param queryStr
485
     * @return
486
     */
487
    protected int countResult(String queryStr) {
488
        Query query = getSession().createQuery(queryStr);
489
        return ((Long)query.uniqueResult()).intValue();
490
    }
491
    /**
492
     * {@inheritDoc}
493
     */
494
    @Override
495
    public int countSecundumForSubtreeSynonyms(TreeIndex subTreeIndex, Reference newSec,
496
            boolean overwriteExisting, boolean includeSharedTaxa, boolean emptySecundumDetail) {
497
        String queryStr = synonymForSubtreeQueryStr(includeSharedTaxa, subTreeIndex, SelectMode.COUNT);
498
        if (!overwriteExisting){
499
            queryStr += " AND syn.sec IS NULL ";
500
        }
501
        return countResult(queryStr);
502
    }
503

  
468 504

  
469 505
    /**
470 506
     * {@inheritDoc}
471 507
     */
472 508
    //#3465
473 509
    @Override
474
    public Set<TaxonBase> setSecundumForSubtreeAcceptedTaxa(TreeIndex subTreeIndex, Reference newSec, boolean overwriteExisting, boolean includeSharedTaxa, boolean emptyDetail) {
510
    public Set<TaxonBase> setSecundumForSubtreeAcceptedTaxa(TreeIndex subTreeIndex, Reference newSec,
511
            boolean overwriteExisting, boolean includeSharedTaxa, boolean emptyDetail, IProgressMonitor monitor) {
475 512
        //for some reason this does not work, maybe because the listeners are not activated,
476
        //but also the first taxon for some reason does not get updated in terms of secundum, but only by the udpate listener
513
        //but also the first taxon for some reason does not get updated in terms of secundum, but only by the update listener
477 514
//        String where = "SELECT t.id FROM TaxonNode tn JOIN tn.taxon t " +
478 515
//                " WHERE tn.treeIndex like '%s%%' ORDER BY t.id";
479 516
//        where = String.format(where, subTreeIndex.toString());
......
485 522
//        query.setParameter("newSec", newSec);
486 523
//        int n = query.executeUpdate();
487 524

  
488
        String queryStr = acceptedForSubtreeQueryStr(includeSharedTaxa, subTreeIndex);
525
        String queryStr = acceptedForSubtreeQueryStr(includeSharedTaxa, subTreeIndex, SelectMode.ID);
489 526
        if (!overwriteExisting){
490 527
            queryStr += " AND t.sec IS NULL ";
491 528
        }
492
        return setSecundum(newSec, emptyDetail, queryStr);
529
        return setSecundum(newSec, emptyDetail, queryStr, monitor);
493 530

  
494 531
    }
495 532

  
496 533
    @Override
497
    public Set<TaxonBase> setSecundumForSubtreeSynonyms(TreeIndex subTreeIndex, Reference newSec, boolean overwriteExisting, boolean includeSharedTaxa, boolean emptyDetail) {
534
    public Set<TaxonBase> setSecundumForSubtreeSynonyms(TreeIndex subTreeIndex, Reference newSec,
535
            boolean overwriteExisting, boolean includeSharedTaxa, boolean emptyDetail, IProgressMonitor monitor) {
498 536

  
499
        String queryStr = synonymForSubtreeQueryStr(includeSharedTaxa, subTreeIndex);
537
        String queryStr = synonymForSubtreeQueryStr(includeSharedTaxa, subTreeIndex, SelectMode.ID);
500 538
        if (!overwriteExisting){
501 539
            queryStr += " AND syn.sec IS NULL ";
502 540
        }
503
        return setSecundum(newSec, emptyDetail, queryStr);
541
        return setSecundum(newSec, emptyDetail, queryStr, monitor);
504 542
    }
505 543
    /**
506 544
     * @param newSec
507 545
     * @param emptyDetail
508 546
     * @param queryStr
547
     * @param monitor
509 548
     * @return
510 549
     */
511 550
    @SuppressWarnings("unchecked")
512
    private <T extends TaxonBase<?>> Set<T> setSecundum(Reference newSec, boolean emptyDetail, String queryStr) {
513
        Query query = getSession().createQuery(queryStr);
514
        @SuppressWarnings("unchecked")
515
        List<T> synonymList = query.list();
516
        MergeResult mergeResult;
551
    private <T extends TaxonBase<?>> Set<T> setSecundum(Reference newSec, boolean emptyDetail, String queryStr, IProgressMonitor monitor) {
517 552
        Set<T> result = new HashSet<>();
518
        for (T taxonBase : synonymList){
519
            if (taxonBase != null){
520
                taxonBase = (T) taxonDao.load(taxonBase.getUuid());
521
                taxonBase.setSec(newSec);
522
                if (emptyDetail){
523
                    taxonBase.setSecMicroReference(null);
553
        Query query = getSession().createQuery(queryStr);
554
        List<List<Integer>> partitionList = splitIdList(query.list(), DEFAULT_PARTITION_SIZE);
555
        for (List<Integer> taxonIdList : partitionList){
556
            List<TaxonBase> taxonList = taxonDao.loadList(taxonIdList, null);
557
            for (TaxonBase taxonBase : taxonList){
558
                if (taxonBase != null){
559
                    taxonBase = taxonDao.load(taxonBase.getUuid());
560
                    taxonBase.setSec(newSec);
561
                    if (emptyDetail){
562
                        taxonBase.setSecMicroReference(null);
563
                    }
564
                    result.add((T)CdmBase.deproxy(taxonBase));
565
                    monitor.worked(1);
566
                    if (monitor.isCanceled()){
567
                        return result;
568
                    }
524 569
                }
525
               result.add(taxonBase);
526 570
            }
571
        }
572
        return result;
573
    }
527 574

  
575
    private List<List<Integer>> splitIdList(List<Integer> idList, Integer size){
576
        List<List<Integer>> result = new ArrayList<>();
577
        for (int i = 0; (i*size)<idList.size(); i++) {
578
            int upper = Math.min((i+1)*size, idList.size());
579
            result.add(idList.subList(i*size, upper));
528 580
        }
529
      return result;
581
        return result;
530 582
    }
531 583

  
532 584

  
......
535 587
     */
536 588
    @Override
537 589
    public Set<TaxonBase> setPublishForSubtreeAcceptedTaxa(TreeIndex subTreeIndex, boolean publish,
538
            boolean includeSharedTaxa) {
539
        String queryStr = acceptedForSubtreeQueryStr(includeSharedTaxa, subTreeIndex);
540
        return setPublish(publish, queryStr);
590
            boolean includeSharedTaxa, IProgressMonitor monitor) {
591
        String queryStr = acceptedForSubtreeQueryStr(includeSharedTaxa, subTreeIndex, SelectMode.ID);
592
        return setPublish(publish, queryStr, monitor);
541 593
    }
542 594

  
543 595
    /**
......
545 597
     */
546 598
    @Override
547 599
    public Set<TaxonBase> setPublishForSubtreeSynonyms(TreeIndex subTreeIndex, boolean publish,
548
            boolean includeSharedTaxa) {
549
        String queryStr = synonymForSubtreeQueryStr(includeSharedTaxa, subTreeIndex);
550
        return setPublish(publish, queryStr);
600
            boolean includeSharedTaxa, IProgressMonitor monitor) {
601
        String queryStr = synonymForSubtreeQueryStr(includeSharedTaxa, subTreeIndex, SelectMode.ID);
602
        return setPublish(publish, queryStr, monitor);
551 603
    }
552 604

  
605
    private static final int DEFAULT_PARTITION_SIZE = 100;
553 606
    /**
554 607
     * @param publish
555 608
     * @param queryStr
556 609
     * @return
557 610
     */
558
    private <T extends TaxonBase<?>> Set<T> setPublish(boolean publish, String queryStr) {
611
    private <T extends TaxonBase<?>> Set<T> setPublish(boolean publish, String queryStr, IProgressMonitor monitor) {
612
        Set<T> result = new HashSet<>();
559 613
        Query query = getSession().createQuery(queryStr);
560 614
        @SuppressWarnings("unchecked")
561
        List<T> taxonList = query.list();
562
        Set<T> result = new HashSet<>();
563
        for (T taxon : taxonList){
564
            taxon = (T)taxonDao.load(taxon.getUuid());
565
            taxon.setPublish(publish);
566
            result.add(taxon);
615
        List<List<Integer>> partitionList = splitIdList(query.list(), DEFAULT_PARTITION_SIZE);
616
        for (List<Integer> taxonIdList : partitionList){
617
            List<TaxonBase> taxonList = taxonDao.loadList(taxonIdList, null);
618
            for (TaxonBase taxonBase : taxonList){
619
                if (taxonBase != null){
620
                    taxonBase.setPublish(publish);
621
                    result.add((T)CdmBase.deproxy(taxonBase));
622
                    monitor.worked(1);
623
                    if (monitor.isCanceled()){
624
                        return result;
625
                    }
626
                }
627
            }
567 628
        }
568 629
        return result;
569 630
    }
......
574 635
     * @param subTreeIndex
575 636
     * @return
576 637
     */
577
    private String synonymForSubtreeQueryStr(boolean includeSharedTaxa, TreeIndex subTreeIndex) {
578
        String queryStr = "SELECT syn "
638
    private String synonymForSubtreeQueryStr(boolean includeSharedTaxa, TreeIndex subTreeIndex, SelectMode mode) {
639
        String queryStr = "SELECT " + mode.hql("syn")
579 640
                + " FROM TaxonNode tn JOIN tn.taxon t JOIN t.synonyms syn"
580 641
                + " WHERE tn.treeIndex like '%s%%' ";
581 642
        if (!includeSharedTaxa){
......
586 647
        return queryStr;
587 648
    }
588 649

  
589
    private String acceptedForSubtreeQueryStr(boolean includeSharedTaxa, TreeIndex subTreeIndex) {
590
        String queryStr = "SELECT t "
650
    private enum SelectMode{
651
        COUNT(" count(*) "),
652
        ID ("id "),
653
        UUID("uuid "),
654
        FULL("");
655
        private String hql;
656
        SelectMode(String hql){
657
            this.hql = hql;
658
        }
659
        public String hql(String prefix){
660
            switch (this){
661
            case ID:
662
            case UUID:
663
                return CdmUtils.Nz(prefix)+"." + hql;
664
            case FULL:
665
                return CdmUtils.Nz(prefix) + hql;
666
            case COUNT:
667
            default: return hql;
668
            }
669

  
670
        }
671
    }
672

  
673
    private String acceptedForSubtreeQueryStr(boolean includeSharedTaxa, TreeIndex subTreeIndex, SelectMode mode) {
674
        String queryStr = "SELECT " + mode.hql("t")
591 675
                + " FROM TaxonNode tn JOIN tn.taxon t "
592 676
                + " WHERE tn.treeIndex like '%s%%' ";
593 677
        if (!includeSharedTaxa){
......
599 683
    }
600 684

  
601 685

  
686

  
602 687
}
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/ITaxonNodeDao.java
15 15
import java.util.Set;
16 16
import java.util.UUID;
17 17

  
18
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
18 19
import eu.etaxonomy.cdm.model.common.TreeIndex;
19 20
import eu.etaxonomy.cdm.model.reference.Reference;
20 21
import eu.etaxonomy.cdm.model.taxon.Classification;
......
123 124
     * @param treeIndexSet set of taxon node tree indexes
124 125
     * @return map with treeindex and uuidAndTitleCache of the represented taxon
125 126
     */
126
    Map<TreeIndex, UuidAndTitleCache<?>> taxonUuidsForTreeIndexes(Collection<TreeIndex> treeIndexSet);
127
    public Map<TreeIndex, UuidAndTitleCache<?>> taxonUuidsForTreeIndexes(Collection<TreeIndex> treeIndexSet);
128

  
127 129

  
128
    /**
129
     * @param ref
130
     * @return
131
     */
132
    public Set<TaxonBase> setSecundumForSubtreeAcceptedTaxa(TreeIndex subTreeIndex, Reference newSec, boolean overwriteExisting, boolean includeSharedTaxa, boolean emptyDetail);
133 130

  
134 131
    /**
135
     * @param ref
132
     * @param subTreeIndex
133
     * @param newSec
134
     * @param overwriteExistingAccepted
135
     * @param includeSharedTaxa
136
     * @param emptySecundumDetail
137
     * @return
136 138
     */
137
    public  Set<TaxonBase> setSecundumForSubtreeSynonyms(TreeIndex subTreeIndex, Reference newSec, boolean overwriteExisting, boolean includeSharedTaxa, boolean emptyDetail);
139
    public int countSecundumForSubtreeAcceptedTaxa(TreeIndex subTreeIndex, Reference newSec,
140
            boolean overwriteExistingAccepted, boolean includeSharedTaxa, boolean emptySecundumDetail);
138 141

  
139 142
    /**
140 143
     * @param subTreeIndex
141
     * @param publish
144
     * @param newSec
145
     * @param overwriteExistingSynonyms
142 146
     * @param includeSharedTaxa
147
     * @param emptySecundumDetail
143 148
     * @return
144 149
     */
145
    public Set<TaxonBase> setPublishForSubtreeAcceptedTaxa(TreeIndex subTreeIndex, boolean publish, boolean includeSharedTaxa);
150
    public int countSecundumForSubtreeSynonyms(TreeIndex subTreeIndex, Reference newSec,
151
            boolean overwriteExistingSynonyms, boolean includeSharedTaxa, boolean emptySecundumDetail);
146 152

  
147 153
    /**
148 154
     * @param subTreeIndex
149
     * @param publish
155
     * @param newSec
156
     * @param overwriteExisting
150 157
     * @param includeSharedTaxa
158
     * @param emptyDetail
159
     * @param monitor
151 160
     * @return
152 161
     */
162
    public Set<TaxonBase> setSecundumForSubtreeAcceptedTaxa(TreeIndex subTreeIndex, Reference newSec, boolean overwriteExisting, boolean includeSharedTaxa, boolean emptyDetail, IProgressMonitor monitor);
163

  
164
    public  Set<TaxonBase> setSecundumForSubtreeSynonyms(TreeIndex subTreeIndex, Reference newSec, boolean overwriteExisting, boolean includeSharedTaxa, boolean emptyDetail, IProgressMonitor monitor);
165

  
166
    public Set<TaxonBase> setPublishForSubtreeAcceptedTaxa(TreeIndex subTreeIndex, boolean publish, boolean includeSharedTaxa, IProgressMonitor monitor);
167

  
153 168
    public Set<TaxonBase> setPublishForSubtreeSynonyms(TreeIndex subTreeIndex, boolean publish,
154
            boolean includeSharedTaxa);
169
            boolean includeSharedTaxa, IProgressMonitor monitor);
155 170

  
156 171
    /**
157 172
     * @param parent
158 173
     * @return
159 174
     */
160
    List<TaxonNodeDto> listChildNodesAsTaxonNodeDto(UuidAndTitleCache<TaxonNode> parent);
175
    public List<TaxonNodeDto> listChildNodesAsTaxonNodeDto(UuidAndTitleCache<TaxonNode> parent);
176

  
161 177

  
162 178
}
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/TaxonNodeServiceImpl.java
825 825
        if (config.getNewSecundum() != null){
826 826
            newSec = refService.load(config.getNewSecundum().getUuid());
827 827
        }
828
        if (subTree != null){
829
            subTreeIndex = TreeIndex.NewInstance(subTree.treeIndex());
830
            Long count = dao.countChildrenOf(subTree, subTree.getClassification(), true);
831
            int intCount = count.intValue();
832
            monitor.beginTask("Update Secundum Reference", intCount);
833
        }
834

  
835 828

  
836 829
        if (config.getSubtreeUuid() == null){
837 830
            result.setError();
......
845 838
            result.addException(new NullPointerException("Subtree does not exist"));
846 839
            monitor.done();
847 840
            return result;
841
        }else{
842
            subTreeIndex = TreeIndex.NewInstance(subTree.treeIndex());
843
            int count = config.isIncludeAcceptedTaxa() ? dao.countSecundumForSubtreeAcceptedTaxa(subTreeIndex, newSec, config.isOverwriteExistingAccepted(), config.isIncludeSharedTaxa(), config.isEmptySecundumDetail()):0;
844
            count += config.isIncludeSynonyms() ? dao.countSecundumForSubtreeSynonyms(subTreeIndex, newSec, config.isOverwriteExistingSynonyms(), config.isIncludeSharedTaxa() , config.isEmptySecundumDetail()) :0;
845
//          Long count = dao.countChildrenOf(subTree, subTree.getClassification(), true);
846
            monitor.beginTask("Update Secundum Reference", count);
848 847
        }
849 848

  
850

  
851 849
        //Reference ref = config.getNewSecundum();
852 850
        if (config.isIncludeAcceptedTaxa()){
853 851
            monitor.subTask("Update Accepted Taxa");
854 852

  
855
            Set<TaxonBase> updatedTaxa = dao.setSecundumForSubtreeAcceptedTaxa(subTreeIndex, newSec, config.isOverwriteExistingAccepted(), config.isIncludeSharedTaxa(), config.isEmptySecundumDetail());
853
            Set<TaxonBase> updatedTaxa = dao.setSecundumForSubtreeAcceptedTaxa(subTreeIndex, newSec, config.isOverwriteExistingAccepted(), config.isIncludeSharedTaxa(), config.isEmptySecundumDetail(), monitor);
856 854
            result.addUpdatedObjects(updatedTaxa);
857 855
        }
858 856
        if (config.isIncludeSynonyms()){
859 857
           monitor.subTask("Update Synonyms");
860
           Set<TaxonBase> updatedSynonyms = dao.setSecundumForSubtreeSynonyms(subTreeIndex, newSec, config.isOverwriteExistingSynonyms(), config.isIncludeSharedTaxa() , config.isEmptySecundumDetail());
858
           Set<TaxonBase> updatedSynonyms = dao.setSecundumForSubtreeSynonyms(subTreeIndex, newSec, config.isOverwriteExistingSynonyms(), config.isIncludeSharedTaxa() , config.isEmptySecundumDetail(), monitor);
861 859
           result.addUpdatedObjects(updatedSynonyms);
862 860
        }
863 861

  
......
897 895

  
898 896
        if (includeAcceptedTaxa){
899 897
            monitor.subTask("Update Accepted Taxa");
900
            Set<TaxonBase> updatedTaxa = dao.setPublishForSubtreeAcceptedTaxa(subTreeIndex, publish, includeSharedTaxa);
898
            Set<TaxonBase> updatedTaxa = dao.setPublishForSubtreeAcceptedTaxa(subTreeIndex, publish, includeSharedTaxa, monitor);
901 899
//            taxonService.saveOrUpdate(updatedTaxa);
902 900
            result.addUpdatedObjects(updatedTaxa);
903 901
        }
904 902
        if (includeSynonyms){
905 903
            monitor.subTask("Update Synonyms");
906
            Set<TaxonBase> updatedSynonyms = dao.setPublishForSubtreeSynonyms(subTreeIndex, publish, includeSharedTaxa);
904
            Set<TaxonBase> updatedSynonyms = dao.setPublishForSubtreeSynonyms(subTreeIndex, publish, includeSharedTaxa, monitor);
907 905
//            taxonService.saveOrUpdate(updatedSynonyms);
908 906
            result.addUpdatedObjects(updatedSynonyms);
909 907
        }

Also available in: Unified diff