Project

General

Profile

Revision 19c6f3d6

ID19c6f3d68236d3027d7dfc0dbc9787a18f53e13b
Parent 1a99fd98
Child b5006f81

Added by Andreas Müller over 2 years ago

ref #7175, ref #7180, ref #7165, ref #7166 Adapting TaxonNodeFilter for unpublished, minMaxRank and areas

View differences:

cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/cdmLight/CdmLightClassificationExport.java
208 208
            state.getResult().setState(ExportResultState.INCOMPLETE_WITH_ERROR);
209 209
        }else{
210 210
            Taxon taxon = taxonNode.getTaxon();
211
            if (state.getConfig().isOnlyPublishedTaxa() && !taxon.isPublish()){
211
            if (!state.getConfig().isIncludeUnpublishedTaxa() && !taxon.isPublish()){
212 212
                return;
213 213
            }
214 214

  
......
685 685
     */
686 686
    private void handleSynonym(CdmLightExportState state, Synonym syn) {
687 687
       try {
688
           if (!syn.isPublish() && state.getConfig().isOnlyPublishedTaxa()){
688
           if (!syn.isPublish() && !state.getConfig().isIncludeUnpublishedTaxa()){
689 689
               return;
690 690
           }
691 691
           TaxonName name = syn.getName();
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/common/ExportConfiguratorBase.java
35 35
	private ICdmDataSource source;
36 36
	private DEST destination;
37 37
	protected IDatabase sourceReference;
38
	protected boolean onlyPublishedTaxa;
38
	protected boolean includeUnpublishedTaxa;
39 39

  
40 40
    protected Class<ICdmIO>[] ioClassList;
41 41

  
......
141 141
	}
142 142

  
143 143

  
144
    public boolean isOnlyPublishedTaxa() {
145
        return onlyPublishedTaxa;
144
    public boolean isIncludeUnpublishedTaxa() {
145
        return includeUnpublishedTaxa;
146 146
    }
147 147

  
148 148

  
149
    public void setOnlyPublishedTaxa(boolean onlyPublishedTaxa) {
150
        this.onlyPublishedTaxa = onlyPublishedTaxa;
149
    public void setIncludeUnpublishedTaxa(boolean includeUnpublished) {
150
        this.includeUnpublishedTaxa = includeUnpublished;
151 151
    }
152 152

  
153 153
	/**
cdmlib-model/src/main/java/eu/etaxonomy/cdm/filter/TaxonNodeFilter.java
46 46

  
47 47
    private boolean includeRootNodes = false;
48 48

  
49
    private boolean includeUnpublished = false;
50

  
49 51
    //********************** FACTORY ***************************/
50 52

  
51 53
    public static TaxonNodeFilter NewTaxonNodeInstance(UUID taxonNodeUuid){
......
79 81
    }
80 82

  
81 83
    public static TaxonNodeFilter NewRankInstance(Rank rankMin, Rank rankMax){
82
        return new TaxonNodeFilter().orRank(rankMin, rankMax);
84
        return new TaxonNodeFilter().setRankMin(rankMin).setRankMax(rankMax);
83 85
    }
84 86

  
85 87
    public static TaxonNodeFilter NewInstance(Collection<UUID> classificationUuids,
86 88
            Collection<UUID> subtreeUuids, Collection<UUID> taxonNodeUuids,
87
            Collection<UUID> taxonUuids){
89
            Collection<UUID> taxonUuids, Collection<UUID> areaUuids,
90
            UUID minRank, UUID maxRank){
88 91

  
89
        TaxonNodeFilter result = new TaxonNodeFilter();
92
        TaxonNodeFilter result = new TaxonNodeFilter().setRankMin(minRank).setRankMax(maxRank);
90 93
        classificationUuids = classificationUuids == null ? new ArrayList<>(): classificationUuids;
91 94
        subtreeUuids = subtreeUuids == null ? new ArrayList<>(): subtreeUuids;
92 95
        taxonNodeUuids = taxonNodeUuids == null ? new ArrayList<>(): taxonNodeUuids;
93 96
        taxonUuids = taxonUuids == null ? new ArrayList<>(): taxonUuids;
97
        areaUuids = areaUuids == null ? new ArrayList<>(): areaUuids;
94 98

  
95 99
        for (UUID uuid : classificationUuids){
96 100
            result.orClassification(uuid);
......
104 108
        for (UUID uuid : taxonUuids){
105 109
            result.orTaxon(uuid);
106 110
        }
111
        for (UUID uuid : areaUuids){
112
            result.orArea(uuid);
113
        }
107 114
        return result;
108 115

  
109 116
    }
......
114 121
        reset();
115 122
    }
116 123

  
124
    /**
125
     * Constructor for a given subtree represented by a {@link TaxonNode}
126
     */
117 127
    public TaxonNodeFilter(TaxonNode node){
118 128
        reset();
119 129
        LogicFilter<TaxonNode> filter = new LogicFilter<>(node);
......
123 133
    public TaxonNodeFilter(Rank rankMin, Rank rankMax){
124 134
        reset();
125 135
        if(rankMin!=null){
126
            this.rankMin = new LogicFilter<Rank>(rankMin);
136
            this.rankMin = new LogicFilter<>(rankMin);
127 137
        }
128 138
        if(rankMax!=null){
129
            this.rankMax = new LogicFilter<Rank>(rankMax);
139
            this.rankMax = new LogicFilter<>(rankMax);
130 140
        }
131 141
    }
132 142

  
......
233 243
        return this;
234 244
    }
235 245

  
246
    /**
247
     * Adds a single {@link TaxonNode} to the filter.<BR><BR>
248
     * NOTE: this adds only the node to the filter, not it's children!
249
     */
236 250
    public TaxonNodeFilter orTaxonNode(TaxonNode taxonNode){
237 251
        taxonNodes.add( new LogicFilter<>(taxonNode, Op.OR));
238 252
        return this;
239 253
    }
254
    /**
255
     * Adds a single {@link TaxonNode} to the filter.<BR><BR>
256
     * NOTE: this adds only the node to the filter, not it's children!
257
     */
240 258
    public TaxonNodeFilter orTaxonNode(UUID uuid){
241 259
        taxonNodes.add( new LogicFilter<>(TaxonNode.class, uuid, Op.OR));
242 260
        return this;
......
246 264
        taxonNodes.add( new LogicFilter<>(taxonNode, Op.NOT));
247 265
        return this;
248 266
    }
249

  
250 267
    public TaxonNodeFilter andTaxonNode(TaxonNode taxonNode){
251 268
        taxonNodes.add(new LogicFilter<>(taxonNode, Op.AND));
252 269
        return this;
......
266 283
        areaFilter.add( new LogicFilter<>(NamedArea.class, uuid, Op.OR));
267 284
        return this;
268 285
    }
286
    public TaxonNodeFilter orArea(NamedArea area){
287
        areaFilter.add( new LogicFilter<>(area, Op.OR));
288
        return this;
289
    }
269 290

  
270 291
    public TaxonNodeFilter andArea(UUID uuid){
271 292
        areaFilter.add( new LogicFilter<>(NamedArea.class, uuid, Op.AND));
272 293
        return this;
273 294
    }
295
    public TaxonNodeFilter andArea(NamedArea area){
296
        areaFilter.add( new LogicFilter<>(area, Op.AND));
297
        return this;
298
    }
274 299

  
275
    public TaxonNodeFilter orRank(Rank rankMin, Rank rankMax){
276
        if(rankMin!=null){
277
            this.rankMin = new LogicFilter<Rank>(rankMin);
278
        }
279
        if(rankMax!=null){
280
            this.rankMax = new LogicFilter<>(rankMax);
281
        }
300

  
301
    public TaxonNodeFilter setRankMin(Rank rankMin){
302
        this.rankMin = rankMin == null? null : new LogicFilter<>(rankMin, Op.AND);
303
        return this;
304
    }
305
    public TaxonNodeFilter setRankMin(UUID rankMinUuid){
306
        this.rankMin = rankMinUuid == null? null : new LogicFilter<>(Rank.class, rankMinUuid, Op.AND);
282 307
        return this;
283 308
    }
284 309

  
285
    public TaxonNodeFilter andRank(Rank rankMin, Rank rankMax){
286
        if(rankMin!=null){
287
            this.rankMin = new LogicFilter<Rank>(rankMin, Op.AND);
288
        }
289
        if(rankMax!=null){
290
            this.rankMax = new LogicFilter<>(rankMax, Op.AND);
291
        }
310
    public TaxonNodeFilter setRankMax(Rank rankMax){
311
        this.rankMax = rankMax == null? null : new LogicFilter<>(rankMax, Op.AND);
312
        return this;
313
    }
314
    public TaxonNodeFilter setRankMax(UUID rankMaxUuid){
315
        this.rankMax = rankMaxUuid == null? null : new LogicFilter<>(Rank.class, rankMaxUuid, Op.AND);
292 316
        return this;
293 317
    }
294 318

  
......
306 330
        return this;
307 331
    }
308 332

  
333
    public LogicFilter<Rank> getRankMax() {
334
        return rankMax;
335
    }
336
    public LogicFilter<Rank> getRankMin() {
337
        return rankMin;
338
    }
339

  
340
    public boolean isIncludeUnpublished() {
341
        return includeUnpublished;
342
    }
343
    public void setIncludeUnpublished(boolean includeUnpublished) {
344
        this.includeUnpublished = includeUnpublished;
345
    }
346

  
347

  
348
    /**
349
     * If <code>true</code> the result will include the root node of
350
     * a classification.
351
     * Note: As a root node per se has no taxon all filters with filter
352
     * on taxon related data have no effect for the root node. If the
353
     * root node is returned only depends on the
354
     * {@link TaxonNodeFilter#isIncludeRootNodes() includeRootNodes}
355
     * parameter.
356
     */
309 357
    public boolean isIncludeRootNodes() {
310 358
        return includeRootNodes;
311 359
    }
......
314 362
        return this;
315 363
    }
316 364

  
317
    public LogicFilter<Rank> getRankMax() {
318
        return rankMax;
319
    }
320

  
321
    public LogicFilter<Rank> getRankMin() {
322
        return rankMin;
323
    }
324

  
325 365
}
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonNodeFilterDaoHibernateImpl.java
39 39

  
40 40
    private static final String FEATURE_UUID = "9fc9d10c-ba50-49ee-b174-ce83fc3f80c6";
41 41

  
42
    private static final String HQL_TRUE = " 1 "; //maybe we can/should use 'true' instead, needs to be checked for all DB types
43

  
42 44
    @Autowired
43 45
    private ITaxonNodeDao taxonNodeDao;
44 46

  
......
100 102
        String rankMaxFilter = getRankMaxFilter(filter);
101 103
        String rankMinFilter = getRankMinFilter(filter);
102 104
        String areaFilter = getAreaFilter(filter);
105
        String unpublishFilter = getUnpublishFilter(filter);
106

  
103 107
        String fullFilter = getFullFilter(subtreeFilter, taxonNodeFilter,
104 108
                classificationFilter, taxonFilter,
105
                rankMaxFilter, rankMinFilter, areaFilter, rootNodeFilter);
109
                rankMaxFilter, rankMinFilter, areaFilter, rootNodeFilter,
110
                unpublishFilter);
106 111
//        String groupBy = " GROUP BY tn.uuid ";
107 112
        String groupBy = "";
108 113
        String fullQuery = select + from + " WHERE " + fullFilter + groupBy;
......
112 117

  
113 118
    private String getFrom(TaxonNodeFilter filter){
114 119
        String from = " FROM TaxonNode tn ";
120
        if (hasTaxonFilter(filter)){
121
            from += " LEFT JOIN tn.taxon taxon ";  //LEFT to allow includeRootNode
122
        }
115 123
        if(!filter.getAreaFilter().isEmpty()){
116
            from += "inner join tn.taxon.descriptions descriptions inner join descriptions.descriptionElements "+DESCRIPTION_ELEMENTS+" ";
124
            from += " INNER JOIN taxon.descriptions descriptions "
125
                  + " INNER JOIN descriptions.descriptionElements " + DESCRIPTION_ELEMENTS + " ";
117 126
        }
118 127
        return from;
119 128
    }
120 129

  
130
    /**
131
     * @return
132
     */
133
    private boolean hasTaxonFilter(TaxonNodeFilter filter) {
134
        boolean result = !filter.getAreaFilter().isEmpty()
135
                || !filter.isIncludeUnpublished();
136
        return result;
137
    }
138

  
139

  
121 140
    private String getAreaFilter(TaxonNodeFilter filter) {
122 141
        String result = "";
123 142
        List<LogicFilter<NamedArea>> areaFilter = filter.getAreaFilter();
......
162 181
        return result;
163 182
    }
164 183

  
184
    private String getUnpublishFilter(TaxonNodeFilter filter) {
185
        String result = "";
186
        if (!filter.isIncludeUnpublished()){
187
            result = " ( taxon.publish = "+HQL_TRUE+" OR tn.parent IS NULL ) ";
188
        }
189
        return result;
190
    }
191

  
165 192

  
166 193
    /**
167 194
     * @param subtreeFilter
......
174 201
     * @return
175 202
     */
176 203
    private String getFullFilter(String subtreeFilter, String taxonNodeFilter, String classificationFilter,
177
            String taxonFilter, String rankMaxFilter, String rankMinFilter, String areaFilter, String rootNodeFilter) {
204
            String taxonFilter, String rankMaxFilter, String rankMinFilter, String areaFilter, String rootNodeFilter,
205
            String unpublishFilter) {
178 206
        String result = " (1=1 ";
179 207
        result = CdmUtils.concat(") AND (", result, subtreeFilter, taxonNodeFilter,
180
                classificationFilter, taxonFilter, rankMaxFilter, rankMinFilter, areaFilter, rootNodeFilter) + ") ";
208
                classificationFilter, taxonFilter, rankMaxFilter, rankMinFilter, areaFilter, rootNodeFilter,
209
                unpublishFilter) + ") ";
181 210
        return result;
182 211
    }
183 212

  
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonNodeFilterDaoHibernateImplTest.java
70 70
    private TaxonNode node3;
71 71
    private TaxonNode node4;
72 72
    private TaxonNode node5;
73
    private TaxonNode nodeUnpublished;
73 74
    private Taxon taxon1;
74 75
    private Taxon taxon2;
75 76
    private Taxon taxon3;
76 77
    private Taxon taxon4;
77 78
    private Taxon taxon5;
79
    private Taxon taxonUnpublished;
78 80

  
79 81
    /**
80 82
     * @throws java.lang.Exception
......
84 86
        /*
85 87
         * classification 1
86 88
         *  - node1 (taxon1, Genus, Europe)
87
         *   - node3 (taxon3, Species, Germany)
89
         *   - node3 (taxon3, Species, Germany)  //if subspecies exists in Denmark this is not fully correct !!
88 90
         *    - node4 (taxon4, Subspecies, Denmark)
89 91
         *    - node5 (taxon5, Subspecies)
90 92
         *  - node2 (taxon2, Family, France)
......
97 99
        taxon3 = Taxon.NewInstance(TaxonName.NewInstance(NomenclaturalCode.ICNAFP, Rank.SPECIES(), null, null, null, null, null, null, null, null), null);
98 100
        taxon4 = Taxon.NewInstance(TaxonName.NewInstance(NomenclaturalCode.ICNAFP, Rank.SUBSPECIES(), null, null, null, null, null, null, null, null), null);
99 101
        taxon5 = Taxon.NewInstance(TaxonName.NewInstance(NomenclaturalCode.ICNAFP, Rank.SUBSPECIES(), null, null, null, null, null, null, null, null), null);
102
        taxonUnpublished = Taxon.NewInstance(TaxonName.NewInstance(NomenclaturalCode.ICNAFP, Rank.SUBSPECIES(), null, null, null, null, null, null, null, null), null);
103
        taxonUnpublished.setPublish(false);
100 104

  
101 105
        NamedArea europe = (NamedArea) termDao.load(europeUuid);
102 106
        NamedArea germany = (NamedArea) termDao.load(germanyUuid);
......
118 122
        taxonNodeDao.save(node4);
119 123
        node5 = node3.addChildTaxon(taxon5, citation, microCitation);
120 124
        node5 = taxonNodeDao.save(node5);
125
        nodeUnpublished = node3.addChildTaxon(taxonUnpublished, citation, microCitation);
126
        nodeUnpublished = taxonNodeDao.save(nodeUnpublished);
121 127

  
122 128
        //MergeResult result = taxonNodeDao.merge(node5, true);
123 129
        //node5 = (TaxonNode) result.getMergedEntity();
......
169 175
    })
170 176
    public void testListUuidsByRank() {
171 177
        String message = "wrong number of nodes filtered";
172

  
173
        TaxonNodeFilter filter = new TaxonNodeFilter(Rank.SPECIES(), Rank.GENUS());
178
        TaxonNodeFilter filter = new TaxonNodeFilter();
174 179
        List<UUID> listUuid = filterDao.listUuids(filter);
180
        assertEquals(message, 5, listUuid.size());  //test start condition without rank filter
181

  
182
        filter = new TaxonNodeFilter(Rank.SPECIES(), Rank.GENUS());
183
        listUuid = filterDao.listUuids(filter);
175 184
        assertEquals(message, 2, listUuid.size());
176 185
        Assert.assertTrue(listUuid.contains(node1.getUuid()));
177 186
        Assert.assertTrue(listUuid.contains(node3.getUuid()));
......
198 207
        filter = new TaxonNodeFilter(Rank.KINGDOM(), Rank.ORDER());
199 208
        listUuid = filterDao.listUuids(filter);
200 209
        assertEquals(message, 0, listUuid.size());
210

  
211
        //reset
212
        Rank nullRank = null;
213
        filter.setRankMax(nullRank).setRankMin(nullRank);
214
        listUuid = filterDao.listUuids(filter);
215
        assertEquals("Reseting the rank filters should work", 5, listUuid.size());
216

  
217
        filter = new TaxonNodeFilter(Rank.KINGDOM(), Rank.ORDER());
218
        UUID nullUuid = null;
219
        filter.setRankMax(nullUuid).setRankMin(nullUuid);
220
        listUuid = filterDao.listUuids(filter);
221
        assertEquals("Reseting the rank filters should work", 5, listUuid.size());
201 222
    }
202 223

  
203 224
    @Test
......
246 267
    }
247 268

  
248 269
    @Test
270
    public void testIncludeUnpublished(){
271
        Classification classification = classificationDao.findByUuid(classification1.getUuid());
272
        TaxonNodeFilter filter = new TaxonNodeFilter(classification.getRootNode());
273
        List<UUID> listUuid = filterDao.listUuids(filter);
274
        Assert.assertEquals("All 5 children but not root node should be returned", 5, listUuid.size());
275

  
276
        filter.setIncludeUnpublished(true);
277
        listUuid = filterDao.listUuids(filter);
278
        Assert.assertEquals("All 6 children including unpublished should be returned", 6, listUuid.size());
279

  
280

  
281
        filter.setIncludeRootNodes(true);
282
        listUuid = filterDao.listUuids(filter);
283
        Assert.assertEquals("All 7 children including root node should be returned", 7, listUuid.size());
284

  
285
    }
286

  
287
    @Test
249 288
    public void testListUuidsByClassification() {
250 289
        Classification classification = classificationDao.findByUuid(classification1.getUuid());
251 290

  
......
338 377
        listUuid = filterDao.listUuids(filter);
339 378
        Assert.assertEquals("1 node should remain", 1, listUuid.size());
340 379

  
380
        //New
381
        filter = new TaxonNodeFilter(node1);  //4 children, see above
382
        filter.orClassification(classification.getUuid());//4 children, see above
383

  
384
        filter.setRankMax(Rank.uuidSpecies);
385
        listUuid = filterDao.listUuids(filter);
386
        Assert.assertEquals("3 children should be returned", 3, listUuid.size());
387

  
388
        filter.setRankMin(Rank.uuidSpecies);
389
        listUuid = filterDao.listUuids(filter);
390
        Assert.assertEquals("Only species should be returned", 1, listUuid.size());
391

  
392
        Rank nullRank = null;
393
        filter.setRankMin(nullRank);
394
        filter.setIncludeUnpublished(true);
395
        listUuid = filterDao.listUuids(filter);
396
        Assert.assertEquals("4 children should be returned, including unpublished", 4, listUuid.size());
397

  
398
        NamedArea germany = HibernateProxyHelper.deproxy(termDao.load(germanyUuid), NamedArea.class);
399
        filter.orArea(germany);
400
        listUuid = filterDao.listUuids(filter);
401
        Assert.assertEquals("1 child should be returned", 1, listUuid.size());
341 402
    }
342 403

  
343 404
    @Test
cdmlib-remote/src/main/java/eu/etaxonomy/cdm/remote/controller/checklist/DwcaExportController.java
214 214
            @RequestParam(value = "doReferences", defaultValue="true") Boolean doReferences,
215 215
            @RequestParam(value = "withHigherClassification", defaultValue="false") Boolean withHigherClassification,
216 216
            @RequestParam(value = "includeHeader", defaultValue="false") Boolean includeHeader,
217
//            @RequestParam(value = "includeUnpublished", defaultValue="false") Boolean includeUnpublished,
217
//            @RequestParam(value = "includeUnpublished", defaultValue="false") Boolean includeUnpublished,  //for now we do not allow unpublished data to be exported via webservice as long as read authentication is not implemented
218

  
219
            @RequestParam(value = "area", required = false) final UuidList areaUuids,
220
            @RequestParam(value = "minRank", required = false) final UUID minRank,
221
            @RequestParam(value = "minRank", required = false) final UUID maxRank,
218 222

  
219
//          @RequestParam(value = "area", required = false) final UuidList areas,
220 223
            @RequestParam(value = "downloadTokenValueId", required = false) final String downloadTokenValueId,
221 224
            @RequestParam(value = "priority", required = false) Integer priority,
222 225
            final HttpServletResponse response,
......
273 276
                                    indexMonitorUuid);
274 277

  
275 278
                            TaxonNodeFilter taxonNodeFilter = TaxonNodeFilter.NewInstance(
276
                                    classificationUuids, subtreeUuids, taxonNodeUuids, taxonUuids);
279
                                    classificationUuids, subtreeUuids, taxonNodeUuids, taxonUuids,
280
                                    areaUuids, minRank, maxRank);
277 281
                            DwcaTaxExportConfigurator config = setDwcaTaxExportConfigurator(
278 282
                                    cacheFile, monitor, taxonNodeFilter, doSynonyms, doMisapplieds,
279 283
                                    doVernaculars, doDistributions, doDescriptions, doImages,
280 284
                                    doTypesAndSpecimen, doResourceRelations, doReferences,
281
                                    withHigherClassification, includeHeader, !includeUnpublished );
285
                                    withHigherClassification, includeHeader, includeUnpublished );
282 286
                            performExport(cacheFile, monitor, config,
283 287
                                    downloadTokenValueId, origin, response);
284 288
                        }
......
378 382
            Boolean doTypesAndSpecimen, Boolean doResourceRelations,
379 383
            Boolean doReferences, Boolean withHigherClassification,
380 384
            Boolean includeHeader,
381
            Boolean onlyPublishedTaxa) {
385
            Boolean includeUnpublished) {
382 386

  
383 387
        if(cacheFile == null){
384 388
            String destination = System.getProperty("java.io.tmpdir");
......
402 406
        config.setDoResourceRelations(doResourceRelations);
403 407
        config.setWithHigherClassification(withHigherClassification);
404 408
        config.setHasHeaderLines(includeHeader);
405
        config.setOnlyPublishedTaxa(onlyPublishedTaxa);
409
        config.setIncludeUnpublishedTaxa(includeUnpublished);
406 410

  
407 411
        config.setProgressMonitor(progressMonitor);
408 412

  

Also available in: Unified diff

Add picture from clipboard (Maximum size: 40 MB)