Project

General

Profile

Download (8.37 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2007 EDIT
3
 * European Distributed Institute of Taxonomy
4
 * http://www.e-taxonomy.eu
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version 1.1
7
 * See LICENSE.TXT at the top of this package for the full license terms.
8
 */
9
package eu.etaxonomy.cdm.io.dwca.out;
10

    
11
import java.io.FileNotFoundException;
12
import java.io.IOException;
13
import java.io.UnsupportedEncodingException;
14
import java.util.ArrayList;
15
import java.util.HashSet;
16
import java.util.List;
17
import java.util.Set;
18
import java.util.UUID;
19

    
20
import org.apache.commons.lang.StringUtils;
21
import org.apache.log4j.Logger;
22
import org.springframework.beans.factory.annotation.Autowired;
23

    
24
import eu.etaxonomy.cdm.api.service.IClassificationService;
25
import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
26
import eu.etaxonomy.cdm.common.CdmUtils;
27
import eu.etaxonomy.cdm.model.common.CdmBase;
28
import eu.etaxonomy.cdm.model.common.IOriginalSource;
29
import eu.etaxonomy.cdm.model.common.ISourceable;
30
import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
31
import eu.etaxonomy.cdm.model.location.Country;
32
import eu.etaxonomy.cdm.model.location.NamedArea;
33
import eu.etaxonomy.cdm.model.taxon.Classification;
34
import eu.etaxonomy.cdm.model.taxon.Taxon;
35
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
36
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
37
import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
38

    
39
/**
40
 * @author a.mueller
41
 * @date 18.04.2011
42
 *
43
 */
44
public abstract class DwcaDataExportBase extends DwcaExportBase{
45

    
46
    private static final long serialVersionUID = -5467295551060073610L;
47

    
48
    @SuppressWarnings("unused")
49
    private static final Logger logger = Logger.getLogger(DwcaDataExportBase.class);
50

    
51
    @Autowired
52
    private IClassificationService classificationService;
53

    
54
    @Autowired
55
    private ITaxonNodeService taxonNodeService;
56

    
57
    abstract protected void handleTaxonNode(DwcaTaxExportState state, TaxonNode node)throws IOException, FileNotFoundException, UnsupportedEncodingException;
58

    
59

    
60
    /**
61
     * {@inheritDoc}
62
     */
63
    @Override
64
    public int countSteps(DwcaTaxExportState state) {
65
        //FIXME count without initialization
66
        List<TaxonNode> allNodes =  allNodes(state);
67
        return allNodes.size();
68
    }
69

    
70
    /**
71
     * Returns the list of {@link TaxonNode taxon nodes} that correspond to the
72
     * given filter criteria (e.g. subtreeUUids). If no filter is given
73
     * all taxon nodes of all classifications are returned. If the list has been
74
     * computed before it is taken from the state cache. Nodes that do not have
75
     * a taxon attached are not returned. Instead a warning is given that the node is
76
     * ommitted (empty taxon nodes should not but do exist in CDM databases).
77
     * <BR>
78
     * Preliminary implementation. Better implement API method for this.
79
     */
80
    //TODO unify with similar methods for other exports
81
    protected List<TaxonNode> allNodes(DwcaTaxExportState state) {
82

    
83
        Set<UUID> subtreeUuidSet = state.getConfig().getSubtreeUuids();
84
        if (subtreeUuidSet == null){
85
            subtreeUuidSet = new HashSet<>();
86
        }
87
        //handle empty list as no filter defined
88
        if (subtreeUuidSet.isEmpty()){
89
            List<Classification> classificationList = getClassificationService().list(Classification.class, null, 0, null, null);
90
            for (Classification classification : classificationList){
91
                subtreeUuidSet.add(classification.getRootNode().getUuid());
92
            }
93
        }
94

    
95
        //TODO memory critical to store ALL node
96
        if (state.getAllNodes().isEmpty()){
97
            makeAllNodes(state, subtreeUuidSet);
98
        }
99
        List<TaxonNode> allNodes = state.getAllNodes();
100
        return allNodes;
101
    }
102

    
103
    private void makeAllNodes(DwcaTaxExportState state, Set<UUID> subtreeSet) {
104

    
105
        try {
106
            boolean doSynonyms = false;
107
            boolean recursive = true;
108
            Set<UUID> uuidSet = new HashSet<>();
109

    
110
            for (UUID subtreeUuid : subtreeSet){
111
                UUID tnUuuid = taxonNodeUuid(subtreeUuid);
112
                uuidSet.add(tnUuuid);
113
                List<TaxonNodeDto> records = getTaxonNodeService().pageChildNodesDTOs(tnUuuid,
114
                        recursive, doSynonyms, null, null, null).getRecords();
115
                for (TaxonNodeDto dto : records){
116
                    uuidSet.add(dto.getUuid());
117
                }
118
            }
119
            List<TaxonNode> allNodes =  getTaxonNodeService().find(uuidSet);
120

    
121
            List<TaxonNode> result = new ArrayList<>();
122
            for (TaxonNode node : allNodes){
123
                if(node.getParent()== null){  //root (or invalid) node
124
                    continue;
125
                }
126
                node = CdmBase.deproxy(node);
127
                Taxon taxon = CdmBase.deproxy(node.getTaxon());
128
                if (taxon == null){
129
                    String message = "There is a taxon node without taxon. id=" + node.getId();
130
                    state.getResult().addWarning(message);
131
                    continue;
132
                }
133
                result.add(node);
134
            }
135
            state.setAllNodes(result);
136
        } catch (Exception e) {
137
            String message = "Unexpected exception when trying to compute all taxon nodes";
138
            state.getResult().addException(e, message);
139
        }
140
    }
141

    
142

    
143
    /**
144
     * @param subtreeUuid
145
     * @return
146
     */
147
    private UUID taxonNodeUuid(UUID subtreeUuid) {
148
        TaxonNode node = taxonNodeService.find(subtreeUuid);
149
        if (node == null){
150
            Classification classification = classificationService.find(subtreeUuid);
151
            if (classification != null){
152
                node = classification.getRootNode();
153
            }else{
154
                throw new IllegalArgumentException("Subtree identifier does not exist: " + subtreeUuid);
155
            }
156
        }
157
        return node.getUuid();
158
    }
159

    
160
    /**
161
     * Creates the locationId, locality, countryCode triple
162
     * @param state
163
     * @param record
164
     * @param area
165
     */
166
    protected void handleArea(DwcaTaxExportState state, IDwcaAreaRecord record, NamedArea area, TaxonBase<?> taxon, boolean required) {
167
        if (area != null){
168
            record.setLocationId(area);
169
            record.setLocality(area.getLabel());
170
            if (area.isInstanceOf(Country.class)){
171
                Country country = CdmBase.deproxy(area, Country.class);
172
                record.setCountryCode(country.getIso3166_A2());
173
            }
174
        }else{
175
            if (required){
176
                String message = "Description requires area but area does not exist for taxon " + getTaxonLogString(taxon);
177
                state.getResult().addWarning(message);
178
            }
179
        }
180
    }
181

    
182

    
183
    protected String getTaxonLogString(TaxonBase<?> taxon) {
184
        return taxon.getTitleCache() + "(" + taxon.getId() + ")";
185
    }
186

    
187

    
188
    protected String getSources(ISourceable<?> sourceable, DwcaTaxExportConfigurator config) {
189
        String result = "";
190
        for (IOriginalSource<?> source: sourceable.getSources()){
191
            if (StringUtils.isBlank(source.getIdInSource())){//idInSource indicates that this source is only data provenance, may be changed in future
192
                if (source.getCitation() != null){
193
                    String ref = source.getCitation().getTitleCache();
194
                    result = CdmUtils.concat(config.getSetSeparator(), result, ref);
195
                }
196
            }
197
        }
198
        return result;
199
    }
200

    
201
    protected String getSources3(ISourceable<?> sourceable, DwcaTaxExportConfigurator config) {
202
        String result = "";
203
        for (IOriginalSource<?> source: sourceable.getSources()){
204
                if (source.getCitation() != null){
205
                    String ref = source.getCitation().getTitleCache();
206
                    result = CdmUtils.concat(config.getSetSeparator(), result, ref);
207
                }
208
        }
209
        return result;
210
    }
211

    
212
    protected String getSources2(Set<DescriptionElementSource> set, DwcaTaxExportConfigurator config) {
213
        String result = "";
214
        for(DescriptionElementSource source: set){
215
            if (StringUtils.isBlank(source.getIdInSource())){//idInSource indicates that this source is only data provenance, may be changed in future
216
                if (source.getCitation() != null){
217
                    String ref = source.getCitation().getTitleCache();
218
                    result = CdmUtils.concat(config.getSetSeparator(), result, ref);
219
                }
220
            }
221
        }
222
        return result;
223
    }
224

    
225
}
(1-1/33)