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
|
|
10
|
package eu.etaxonomy.cdm.io.dwca.out;
|
11
|
|
12
|
import java.io.FileNotFoundException;
|
13
|
import java.io.IOException;
|
14
|
import java.io.PrintWriter;
|
15
|
import java.io.UnsupportedEncodingException;
|
16
|
import java.util.Map;
|
17
|
import java.util.Set;
|
18
|
|
19
|
import org.apache.log4j.Logger;
|
20
|
|
21
|
import eu.etaxonomy.cdm.model.common.CdmBase;
|
22
|
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
|
23
|
import eu.etaxonomy.cdm.model.common.Language;
|
24
|
import eu.etaxonomy.cdm.model.common.LanguageString;
|
25
|
import eu.etaxonomy.cdm.model.common.RelationshipBase;
|
26
|
import eu.etaxonomy.cdm.model.common.RelationshipTermBase;
|
27
|
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
|
28
|
import eu.etaxonomy.cdm.model.description.TaxonDescription;
|
29
|
import eu.etaxonomy.cdm.model.description.TaxonInteraction;
|
30
|
import eu.etaxonomy.cdm.model.name.INonViralName;
|
31
|
import eu.etaxonomy.cdm.model.name.NameRelationship;
|
32
|
import eu.etaxonomy.cdm.model.name.TaxonName;
|
33
|
import eu.etaxonomy.cdm.model.taxon.Taxon;
|
34
|
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
|
35
|
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
|
36
|
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
|
37
|
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
|
38
|
|
39
|
/**
|
40
|
* Mapps taxon concept relationships, taxon name relationships and taxon interactions
|
41
|
* @author a.mueller
|
42
|
* @created 20.04.2011
|
43
|
*/
|
44
|
public class DwcaResourceRelationExport extends DwcaDataExportBase {
|
45
|
private static final long serialVersionUID = 33810773244068812L;
|
46
|
|
47
|
private static final Logger logger = Logger.getLogger(DwcaResourceRelationExport.class);
|
48
|
|
49
|
private static final String ROW_TYPE = "http://rs.tdwg.org/dwc/terms/ResourceRelationship";
|
50
|
protected static final String fileName = "resourceRelationship.txt";
|
51
|
|
52
|
private DwcaMetaDataRecord metaRecord;
|
53
|
|
54
|
|
55
|
/**
|
56
|
* Constructor
|
57
|
*/
|
58
|
public DwcaResourceRelationExport(DwcaTaxExportState state) {
|
59
|
super();
|
60
|
this.ioName = this.getClass().getSimpleName();
|
61
|
metaRecord = new DwcaMetaDataRecord(! IS_CORE, fileName, ROW_TYPE);
|
62
|
state.addMetaRecord(metaRecord);
|
63
|
file = DwcaTaxExportFile.RESOURCE_RELATION;
|
64
|
}
|
65
|
|
66
|
@Override
|
67
|
protected void doInvoke(DwcaTaxExportState state){}
|
68
|
|
69
|
|
70
|
@Override
|
71
|
protected void handleTaxonNode(DwcaTaxExportState state, TaxonNode node) throws FileNotFoundException, UnsupportedEncodingException, IOException{
|
72
|
|
73
|
try {
|
74
|
DwcaTaxExportConfigurator config = state.getConfig();
|
75
|
|
76
|
Taxon taxon = CdmBase.deproxy(node.getTaxon());
|
77
|
|
78
|
//taxon interactions
|
79
|
Set<TaxonDescription> descriptions = taxon.getDescriptions();
|
80
|
for (TaxonDescription description : descriptions){
|
81
|
for (DescriptionElementBase el : description.getElements()){
|
82
|
if (el.isInstanceOf(TaxonInteraction.class)){
|
83
|
DwcaResourceRelationRecord record = new DwcaResourceRelationRecord(metaRecord, config);
|
84
|
TaxonInteraction taxonInteraction = CdmBase.deproxy(el,TaxonInteraction.class);
|
85
|
if (! state.recordExistsUuid(taxonInteraction)){
|
86
|
handleInteraction(state, record, taxon, taxonInteraction);
|
87
|
PrintWriter writer = createPrintWriter(state, file);
|
88
|
record.write(state, writer);
|
89
|
state.addExistingRecordUuid(taxonInteraction);
|
90
|
}
|
91
|
}
|
92
|
}
|
93
|
}
|
94
|
|
95
|
//concept relationships
|
96
|
for (TaxonRelationship rel : taxon.getTaxonRelations()){
|
97
|
DwcaResourceRelationRecord record = new DwcaResourceRelationRecord(metaRecord, config);
|
98
|
IdentifiableEntity<?> subject = rel.getFromTaxon();
|
99
|
IdentifiableEntity<?> object = rel.getToTaxon();
|
100
|
|
101
|
if (rel.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR()) ){
|
102
|
//misapplied names are handled in core (tax)
|
103
|
continue;
|
104
|
}
|
105
|
if (! state.recordExistsUuid(rel)){
|
106
|
handleRelationship(record, subject, object, rel, false);
|
107
|
PrintWriter writer = createPrintWriter(state, file);
|
108
|
record.write(state, writer);
|
109
|
state.addExistingRecordUuid(rel);
|
110
|
}
|
111
|
|
112
|
}
|
113
|
|
114
|
//Name relationship
|
115
|
//TODO
|
116
|
INonViralName name = taxon.getName();
|
117
|
if (name == null){
|
118
|
String message = "There is a taxon node without name: " + node.getId();
|
119
|
state.getResult().addError(message, "DwcaResourceRelationExport.makeSingleTaxonNode");
|
120
|
return;
|
121
|
}
|
122
|
Set<NameRelationship> rels = name.getNameRelations();
|
123
|
for (NameRelationship rel : rels){
|
124
|
DwcaResourceRelationRecord record = new DwcaResourceRelationRecord(metaRecord, config);
|
125
|
IdentifiableEntity<?> subject = CdmBase.deproxy(rel.getFromName());
|
126
|
IdentifiableEntity<?> object = CdmBase.deproxy(rel.getToName());
|
127
|
name = CdmBase.deproxy(name);
|
128
|
boolean isInverse = false;
|
129
|
if(subject == name){
|
130
|
subject = taxon;
|
131
|
}else if(object == name){
|
132
|
object = subject;
|
133
|
subject = taxon;
|
134
|
isInverse = true;
|
135
|
}else{
|
136
|
String message = "Both, subject and object, are not part of the relationship for " + name.getTitleCache();
|
137
|
state.getResult().addWarning(message);
|
138
|
}
|
139
|
|
140
|
if (! state.recordExistsUuid(rel)){
|
141
|
//????
|
142
|
handleRelationship(record, subject, object, rel, isInverse);
|
143
|
PrintWriter writer = createPrintWriter(state, file);
|
144
|
record.write(state, writer);
|
145
|
state.addExistingRecordUuid(rel);
|
146
|
}
|
147
|
}
|
148
|
|
149
|
} catch (Exception e) {
|
150
|
String message = "Unexpected exception: " + e.getMessage();
|
151
|
state.getResult().addException(e, message);
|
152
|
}finally{
|
153
|
flushWriter(state, file);
|
154
|
}
|
155
|
|
156
|
return;
|
157
|
}
|
158
|
|
159
|
private void handleRelationship(DwcaResourceRelationRecord record, IdentifiableEntity<?> subject, IdentifiableEntity<?> object,
|
160
|
RelationshipBase<?,?,?> rel, boolean isInverse) {
|
161
|
RelationshipTermBase<?> type = rel.getType();
|
162
|
|
163
|
record.setId(subject.getId());
|
164
|
record.setUuid(subject.getUuid());
|
165
|
|
166
|
|
167
|
record.setResourceRelationshipId(rel.getId());
|
168
|
record.setResourceRelationshipId(rel.getUuid());
|
169
|
//TODO id / uuid / names ??
|
170
|
if (object.isInstanceOf(TaxonBase.class)){
|
171
|
record.setRelatedResourceId(object.getUuid());
|
172
|
}
|
173
|
//TODO transform to controlled voc
|
174
|
String relTypeLabel;
|
175
|
if (isInverse){
|
176
|
relTypeLabel = type.getInverseLabel();
|
177
|
}else{
|
178
|
relTypeLabel = type.getLabel();
|
179
|
}
|
180
|
record.setRelationshipOfResource(relTypeLabel);
|
181
|
record.setRelationshipAccordingTo(rel.getCitation()== null? null : rel.getCitation().getTitleCache());
|
182
|
//TODO missing
|
183
|
record.setRelatioshipEstablishedDate(null);
|
184
|
record.setRelationshipRemarks(rel.getAnnotations());
|
185
|
if (object.isInstanceOf(TaxonName.class)){
|
186
|
record.setScientificName(object.getTitleCache());
|
187
|
}
|
188
|
}
|
189
|
|
190
|
|
191
|
|
192
|
private void handleInteraction(DwcaTaxExportState state, DwcaResourceRelationRecord record, IdentifiableEntity<?> subject, TaxonInteraction interaction) {
|
193
|
Taxon object = interaction.getTaxon2();
|
194
|
if (object == null){
|
195
|
state.getResult().addWarning("Taxon interaction has no target object.");
|
196
|
}
|
197
|
Map<Language, LanguageString> description = interaction.getDescription();
|
198
|
|
199
|
record.setId(subject.getId());
|
200
|
record.setUuid(subject.getUuid());
|
201
|
|
202
|
record.setRelatedResourceId(object == null ? null : object.getUuid());
|
203
|
//TODO transform to controlled voc
|
204
|
if (description != null && description.get(Language.DEFAULT()) != null){
|
205
|
record.setRelationshipOfResource(description.get(Language.DEFAULT()).getText());
|
206
|
}else{
|
207
|
record.setRelationshipOfResource(interaction.getFeature().getLabel());
|
208
|
}
|
209
|
//TODO uuid
|
210
|
record.setResourceRelationshipId(interaction.getId());
|
211
|
record.setResourceRelationshipId(interaction.getUuid());
|
212
|
|
213
|
//FIXME multiple sources
|
214
|
record.setRelationshipAccordingTo(null);
|
215
|
//TODO missing
|
216
|
record.setRelatioshipEstablishedDate(null);
|
217
|
record.setRelationshipRemarks(interaction.getAnnotations());
|
218
|
//TODO does this need to be filled?
|
219
|
record.setScientificName(null);
|
220
|
}
|
221
|
|
222
|
|
223
|
@Override
|
224
|
protected boolean doCheck(DwcaTaxExportState state) {
|
225
|
boolean result = true;
|
226
|
logger.warn("No check implemented for " + this.ioName);
|
227
|
return result;
|
228
|
}
|
229
|
|
230
|
|
231
|
@Override
|
232
|
public boolean isIgnore(DwcaTaxExportState state) {
|
233
|
return ! state.getConfig().isDoResourceRelation();
|
234
|
}
|
235
|
}
|