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.common;
|
11
|
|
12
|
import java.net.MalformedURLException;
|
13
|
import java.net.URI;
|
14
|
import java.net.URISyntaxException;
|
15
|
import java.sql.ResultSet;
|
16
|
import java.sql.SQLException;
|
17
|
import java.util.ArrayList;
|
18
|
import java.util.Arrays;
|
19
|
import java.util.List;
|
20
|
import java.util.Set;
|
21
|
import java.util.UUID;
|
22
|
|
23
|
import org.apache.commons.lang.StringUtils;
|
24
|
import org.apache.log4j.Logger;
|
25
|
|
26
|
import eu.etaxonomy.cdm.api.service.pager.Pager;
|
27
|
import eu.etaxonomy.cdm.common.media.ImageInfo;
|
28
|
import eu.etaxonomy.cdm.io.common.mapping.IInputTransformer;
|
29
|
import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
|
30
|
import eu.etaxonomy.cdm.io.markup.MarkupTransformer;
|
31
|
import eu.etaxonomy.cdm.model.agent.Person;
|
32
|
import eu.etaxonomy.cdm.model.agent.Team;
|
33
|
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
|
34
|
import eu.etaxonomy.cdm.model.common.AnnotationType;
|
35
|
import eu.etaxonomy.cdm.model.common.CdmBase;
|
36
|
import eu.etaxonomy.cdm.model.common.DefinedTerm;
|
37
|
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
|
38
|
import eu.etaxonomy.cdm.model.common.ExtensionType;
|
39
|
import eu.etaxonomy.cdm.model.common.ICdmBase;
|
40
|
import eu.etaxonomy.cdm.model.common.IOriginalSource;
|
41
|
import eu.etaxonomy.cdm.model.common.ISourceable;
|
42
|
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
|
43
|
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
|
44
|
import eu.etaxonomy.cdm.model.common.Language;
|
45
|
import eu.etaxonomy.cdm.model.common.Marker;
|
46
|
import eu.etaxonomy.cdm.model.common.MarkerType;
|
47
|
import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
|
48
|
import eu.etaxonomy.cdm.model.common.OriginalSourceType;
|
49
|
import eu.etaxonomy.cdm.model.common.TermType;
|
50
|
import eu.etaxonomy.cdm.model.common.TermVocabulary;
|
51
|
import eu.etaxonomy.cdm.model.description.DescriptionBase;
|
52
|
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
|
53
|
import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
|
54
|
import eu.etaxonomy.cdm.model.description.Feature;
|
55
|
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
|
56
|
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
|
57
|
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
|
58
|
import eu.etaxonomy.cdm.model.description.State;
|
59
|
import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
|
60
|
import eu.etaxonomy.cdm.model.description.TaxonDescription;
|
61
|
import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
|
62
|
import eu.etaxonomy.cdm.model.description.TextData;
|
63
|
import eu.etaxonomy.cdm.model.location.Country;
|
64
|
import eu.etaxonomy.cdm.model.location.NamedArea;
|
65
|
import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
|
66
|
import eu.etaxonomy.cdm.model.location.NamedAreaType;
|
67
|
import eu.etaxonomy.cdm.model.location.ReferenceSystem;
|
68
|
import eu.etaxonomy.cdm.model.media.ImageFile;
|
69
|
import eu.etaxonomy.cdm.model.media.Media;
|
70
|
import eu.etaxonomy.cdm.model.media.MediaRepresentation;
|
71
|
import eu.etaxonomy.cdm.model.name.INonViralName;
|
72
|
import eu.etaxonomy.cdm.model.name.Rank;
|
73
|
import eu.etaxonomy.cdm.model.name.RankClass;
|
74
|
import eu.etaxonomy.cdm.model.name.TaxonName;
|
75
|
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
|
76
|
import eu.etaxonomy.cdm.model.reference.Reference;
|
77
|
import eu.etaxonomy.cdm.model.taxon.Classification;
|
78
|
import eu.etaxonomy.cdm.model.taxon.Synonym;
|
79
|
import eu.etaxonomy.cdm.model.taxon.Taxon;
|
80
|
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
|
81
|
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
|
82
|
|
83
|
/**
|
84
|
* @author a.mueller
|
85
|
* @created 01.07.2008
|
86
|
*/
|
87
|
public abstract class CdmImportBase<CONFIG extends IImportConfigurator, STATE extends ImportStateBase>
|
88
|
extends CdmIoBase<STATE, ImportResult>
|
89
|
implements ICdmImport<CONFIG, STATE>{
|
90
|
|
91
|
private static final long serialVersionUID = 8730012744209195616L;
|
92
|
private static final Logger logger = Logger.getLogger(CdmImportBase.class);
|
93
|
|
94
|
protected static final boolean CREATE = true;
|
95
|
protected static final boolean IMAGE_GALLERY = true;
|
96
|
protected static final boolean READ_MEDIA_DATA = true;
|
97
|
|
98
|
public static final UUID uuidUserDefinedNamedAreaLevelVocabulary = UUID.fromString("255144da-8d95-457e-a327-9752a8f85e5a");
|
99
|
public static final UUID uuidUserDefinedNamedAreaVocabulary = UUID.fromString("b2238399-a3af-4f6d-b7eb-ff5d0899bf1b");
|
100
|
public static final UUID uuidUserDefinedExtensionTypeVocabulary = UUID.fromString("e28c1394-1be8-4847-8b81-ab44eb6d5bc8");
|
101
|
public static final UUID uuidUserDefinedIdentifierTypeVocabulary = UUID.fromString("194b173b-e2c8-49f1-bbfa-d5d51556cf68");
|
102
|
public static final UUID uuidUserDefinedReferenceSystemVocabulary = UUID.fromString("467591a3-10b4-4bf1-9239-f06ece33e90a");
|
103
|
public static final UUID uuidUserDefinedFeatureVocabulary = UUID.fromString("fe5fccb3-a2f2-4b97-b199-6e2743cf1627");
|
104
|
public static final UUID uuidUserDefinedMeasurementUnitVocabulary = UUID.fromString("d5e72bb7-f312-4080-bb86-c695d04a6e66");
|
105
|
public static final UUID uuidUserDefinedStatisticalMeasureVocabulary = UUID.fromString("62a89836-c730-4b4f-a904-3d859dbfc400");
|
106
|
public static final UUID uuidUserDefinedStateVocabulary = UUID.fromString("f7cddb49-8392-4db1-8640-65b48a0e6d13");
|
107
|
public static final UUID uuidUserDefinedTaxonRelationshipTypeVocabulary = UUID.fromString("31a324dc-408d-4877-891f-098db21744c6");
|
108
|
public static final UUID uuidUserDefinedAnnotationTypeVocabulary = UUID.fromString("cd9ecdd2-9cae-4890-9032-ad83293ae883");
|
109
|
public static final UUID uuidUserDefinedMarkerTypeVocabulary = UUID.fromString("5f02a261-fd7d-4fce-bbe4-21472de8cd51");
|
110
|
public static final UUID uuidUserDefinedRankVocabulary = UUID.fromString("4dc57931-38e2-46c3-974d-413b087646ba");
|
111
|
public static final UUID uuidUserDefinedPresenceAbsenceVocabulary = UUID.fromString("6b8a2581-1471-4ea6-b8ad-b2d931cfbc23");
|
112
|
|
113
|
public static final UUID uuidUserDefinedModifierVocabulary = UUID.fromString("2a8b3838-3a95-49ea-9ab2-3049614b5884");
|
114
|
public static final UUID uuidUserDefinedKindOfUnitVocabulary = UUID.fromString("e7c5deb2-f485-4a66-9104-0c5398efd481");
|
115
|
|
116
|
|
117
|
|
118
|
private static final String UuidOnly = "UUIDOnly";
|
119
|
private static final String UuidLabel = "UUID or label";
|
120
|
private static final String UuidLabelAbbrev = "UUID, label or abbreviation";
|
121
|
private static final String UuidAbbrev = "UUID or abbreviation";
|
122
|
|
123
|
private final static String authorSeparator = ", ";
|
124
|
private final static String lastAuthorSeparator = " & ";
|
125
|
|
126
|
public enum TermMatchMode{
|
127
|
UUID_ONLY(0, UuidOnly)
|
128
|
,UUID_LABEL(1, UuidLabel)
|
129
|
,UUID_LABEL_ABBREVLABEL(2, UuidLabelAbbrev)
|
130
|
,UUID_ABBREVLABEL(3, UuidAbbrev)
|
131
|
;
|
132
|
|
133
|
|
134
|
private final int id;
|
135
|
private final String representation;
|
136
|
private TermMatchMode(int id, String representation){
|
137
|
this.id = id;
|
138
|
this.representation = representation;
|
139
|
}
|
140
|
public int getId() {
|
141
|
return id;
|
142
|
}
|
143
|
public String getRepresentation() {
|
144
|
return representation;
|
145
|
}
|
146
|
public TermMatchMode valueOf(int id){
|
147
|
switch (id){
|
148
|
case 0: return UUID_ONLY;
|
149
|
case 1: return UUID_LABEL;
|
150
|
case 2: return UUID_LABEL_ABBREVLABEL;
|
151
|
case 3: return UUID_ABBREVLABEL;
|
152
|
default: return UUID_ONLY;
|
153
|
}
|
154
|
}
|
155
|
|
156
|
|
157
|
}
|
158
|
|
159
|
@Override
|
160
|
protected ImportResult getNoDataResult(STATE state) {
|
161
|
return ImportResult.NewNoDataInstance();
|
162
|
}
|
163
|
|
164
|
@Override
|
165
|
protected ImportResult getDefaultResult(STATE state) {
|
166
|
return ImportResult.NewInstance();
|
167
|
}
|
168
|
|
169
|
protected Classification makeTree(STATE state, Reference reference){
|
170
|
String treeName = "Classification (Import)";
|
171
|
if (reference != null && StringUtils.isNotBlank(reference.getTitleCache())){
|
172
|
treeName = reference.getTitleCache();
|
173
|
}
|
174
|
Classification tree = Classification.NewInstance(treeName);
|
175
|
tree.setReference(reference);
|
176
|
|
177
|
|
178
|
// use defined uuid for first tree
|
179
|
CONFIG config = (CONFIG)state.getConfig();
|
180
|
if (state.countTrees() < 1 ){
|
181
|
tree.setUuid(config.getClassificationUuid());
|
182
|
}
|
183
|
getClassificationService().save(tree);
|
184
|
state.putTree(reference, tree);
|
185
|
return tree;
|
186
|
}
|
187
|
|
188
|
|
189
|
/**
|
190
|
* Alternative memory saving method variant of
|
191
|
* {@link #makeTree(STATE state, Reference ref)} which stores only the
|
192
|
* UUID instead of the full tree in the <code>ImportStateBase</code> by
|
193
|
* using <code>state.putTreeUuid(ref, tree);</code>
|
194
|
*
|
195
|
* @param state
|
196
|
* @param ref
|
197
|
* @return
|
198
|
*/
|
199
|
protected Classification makeTreeMemSave(STATE state, Reference ref){
|
200
|
String treeName = "Classification (Import)";
|
201
|
if (ref != null && StringUtils.isNotBlank(ref.getTitleCache())){
|
202
|
treeName = ref.getTitleCache();
|
203
|
}
|
204
|
Classification tree = Classification.NewInstance(treeName);
|
205
|
tree.setReference(ref);
|
206
|
|
207
|
|
208
|
// use defined uuid for first tree
|
209
|
CONFIG config = (CONFIG)state.getConfig();
|
210
|
if (state.countTrees() < 1 ){
|
211
|
tree.setUuid(config.getClassificationUuid());
|
212
|
}
|
213
|
getClassificationService().save(tree);
|
214
|
state.putTreeUuid(ref, tree);
|
215
|
return tree;
|
216
|
}
|
217
|
|
218
|
|
219
|
|
220
|
|
221
|
protected ExtensionType getExtensionType(STATE state, UUID uuid, String label, String text, String labelAbbrev){
|
222
|
return getExtensionType(state, uuid, label, text, labelAbbrev, null);
|
223
|
}
|
224
|
protected ExtensionType getExtensionType(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary<ExtensionType> voc){
|
225
|
if (uuid == null){
|
226
|
uuid = UUID.randomUUID();
|
227
|
}
|
228
|
ExtensionType extensionType = state.getExtensionType(uuid);
|
229
|
if (extensionType == null){
|
230
|
extensionType = (ExtensionType)getTermService().find(uuid);
|
231
|
if (extensionType == null){
|
232
|
extensionType = ExtensionType.NewInstance(text, label, labelAbbrev);
|
233
|
extensionType.setUuid(uuid);
|
234
|
if (voc == null){
|
235
|
boolean isOrdered = false;
|
236
|
voc = getVocabulary(TermType.ExtensionType, uuidUserDefinedExtensionTypeVocabulary, "User defined vocabulary for extension types", "User Defined Extension Types", null, null, isOrdered, extensionType);
|
237
|
}
|
238
|
voc.addTerm(extensionType);
|
239
|
getTermService().saveOrUpdate(extensionType);
|
240
|
}
|
241
|
state.putExtensionType(extensionType);
|
242
|
}
|
243
|
return extensionType;
|
244
|
}
|
245
|
|
246
|
protected DefinedTerm getIdentiferType(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary<DefinedTerm> voc){
|
247
|
if (uuid == null){
|
248
|
uuid = UUID.randomUUID();
|
249
|
}
|
250
|
DefinedTerm identifierType = state.getIdentifierType(uuid);
|
251
|
if (identifierType == null){
|
252
|
identifierType = (DefinedTerm)getTermService().find(uuid);
|
253
|
if (identifierType == null){
|
254
|
identifierType = DefinedTerm .NewIdentifierTypeInstance(text, label, labelAbbrev);
|
255
|
identifierType.setUuid(uuid);
|
256
|
if (voc == null){
|
257
|
boolean isOrdered = false;
|
258
|
voc = getVocabulary(TermType.IdentifierType, uuidUserDefinedIdentifierTypeVocabulary, "User defined vocabulary for identifier types", "User Defined Identifier Types", null, null, isOrdered, identifierType);
|
259
|
}
|
260
|
voc.addTerm(identifierType);
|
261
|
getTermService().saveOrUpdate(identifierType);
|
262
|
}
|
263
|
state.putIdentifierType(identifierType);
|
264
|
}
|
265
|
return identifierType;
|
266
|
}
|
267
|
|
268
|
|
269
|
protected MarkerType getMarkerType(STATE state, String keyString) {
|
270
|
IInputTransformer transformer = state.getTransformer();
|
271
|
MarkerType markerType = null;
|
272
|
try {
|
273
|
markerType = transformer.getMarkerTypeByKey(keyString);
|
274
|
} catch (UndefinedTransformerMethodException e) {
|
275
|
logger.info("getMarkerTypeByKey not yet implemented for this import");
|
276
|
}
|
277
|
if (markerType == null ){
|
278
|
UUID uuid;
|
279
|
try {
|
280
|
uuid = transformer.getMarkerTypeUuid(keyString);
|
281
|
return getMarkerType(state, uuid, keyString, keyString, keyString);
|
282
|
} catch (UndefinedTransformerMethodException e) {
|
283
|
logger.warn("getMarkerTypeUuid not yet implemented for this import");
|
284
|
}
|
285
|
}
|
286
|
return null;
|
287
|
}
|
288
|
|
289
|
protected MarkerType getMarkerType(STATE state, UUID uuid, String label, String description, String labelAbbrev){
|
290
|
return getMarkerType(state, uuid, label, description, labelAbbrev, null, null);
|
291
|
}
|
292
|
|
293
|
protected MarkerType getMarkerType(STATE state, UUID uuid, String label, String description, String labelAbbrev, TermVocabulary<MarkerType> voc){
|
294
|
return this.getMarkerType(state, uuid, label, description, labelAbbrev, voc, null);
|
295
|
}
|
296
|
|
297
|
|
298
|
protected MarkerType getMarkerType(STATE state, UUID uuid, String label, String description, String labelAbbrev, TermVocabulary<MarkerType> voc, Language language){
|
299
|
if (uuid == null){
|
300
|
uuid = UUID.randomUUID();
|
301
|
}
|
302
|
MarkerType markerType = state.getMarkerType(uuid);
|
303
|
if (markerType == null){
|
304
|
markerType = (MarkerType)getTermService().find(uuid);
|
305
|
if (markerType == null){
|
306
|
markerType = MarkerType.NewInstance(description, label, labelAbbrev);
|
307
|
if (language != null){
|
308
|
markerType.getRepresentations().iterator().next().setLanguage(language);
|
309
|
}
|
310
|
markerType.setUuid(uuid);
|
311
|
if (voc == null){
|
312
|
boolean isOrdered = false;
|
313
|
voc = getVocabulary(TermType.MarkerType, uuidUserDefinedMarkerTypeVocabulary, "User defined vocabulary for marker types", "User Defined Marker Types", null, null, isOrdered, markerType);
|
314
|
}
|
315
|
voc.addTerm(markerType);
|
316
|
getTermService().save(markerType);
|
317
|
}
|
318
|
state.putMarkerType(markerType);
|
319
|
}
|
320
|
return markerType;
|
321
|
}
|
322
|
|
323
|
protected AnnotationType getAnnotationType(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary<AnnotationType> voc){
|
324
|
if (uuid == null){
|
325
|
uuid = UUID.randomUUID();
|
326
|
}
|
327
|
AnnotationType annotationType = state.getAnnotationType(uuid);
|
328
|
if (annotationType == null){
|
329
|
annotationType = (AnnotationType)getTermService().find(uuid);
|
330
|
if (annotationType == null){
|
331
|
annotationType = AnnotationType.NewInstance(label, text, labelAbbrev);
|
332
|
annotationType.setUuid(uuid);
|
333
|
if (voc == null){
|
334
|
boolean isOrdered = false;
|
335
|
voc = getVocabulary(TermType.AnnotationType, uuidUserDefinedAnnotationTypeVocabulary, "User defined vocabulary for annotation types", "User Defined Annotation Types", null, null, isOrdered, annotationType);
|
336
|
}
|
337
|
|
338
|
voc.addTerm(annotationType);
|
339
|
getTermService().save(annotationType);
|
340
|
}
|
341
|
state.putAnnotationType(annotationType);
|
342
|
}
|
343
|
return annotationType;
|
344
|
}
|
345
|
|
346
|
|
347
|
protected ReferenceSystem getReferenceSystem(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary voc){
|
348
|
if (uuid == null){
|
349
|
uuid = UUID.randomUUID();
|
350
|
}
|
351
|
ReferenceSystem refSystem = state.getReferenceSystem(uuid);
|
352
|
if (refSystem == null){
|
353
|
refSystem = (ReferenceSystem)getTermService().find(uuid);
|
354
|
if (refSystem == null){
|
355
|
refSystem = ReferenceSystem.NewInstance(text, label, labelAbbrev);
|
356
|
if (voc == null){
|
357
|
boolean isOrdered = false;
|
358
|
voc = getVocabulary(TermType.ReferenceSystem, uuidUserDefinedReferenceSystemVocabulary, "User defined vocabulary for reference systems", "User Defined Reference System", null, null, isOrdered, refSystem);
|
359
|
}
|
360
|
voc.addTerm(refSystem);
|
361
|
refSystem.setUuid(uuid);
|
362
|
getTermService().save(refSystem);
|
363
|
}
|
364
|
state.putReferenceSystem(refSystem);
|
365
|
}
|
366
|
return refSystem;
|
367
|
|
368
|
}
|
369
|
|
370
|
|
371
|
|
372
|
protected Rank getRank(STATE state, UUID uuid, String label, String text, String labelAbbrev,OrderedTermVocabulary<Rank> voc, Rank lowerRank, RankClass rankClass){
|
373
|
if (uuid == null){
|
374
|
uuid = UUID.randomUUID();
|
375
|
}
|
376
|
Rank rank = state.getRank(uuid);
|
377
|
if (rank == null){
|
378
|
rank = (Rank)getTermService().find(uuid);
|
379
|
if (rank == null){
|
380
|
rank = Rank.NewInstance(rankClass, text, label, labelAbbrev);
|
381
|
if (voc == null){
|
382
|
boolean isOrdered = true;
|
383
|
voc = (OrderedTermVocabulary)getVocabulary(TermType.Rank, uuidUserDefinedRankVocabulary, "User defined vocabulary for ranks", "User Defined Reference System", null, null, isOrdered, rank);
|
384
|
}
|
385
|
if (lowerRank == null){
|
386
|
voc.addTerm(rank);
|
387
|
}else{
|
388
|
voc.addTermAbove(rank, lowerRank);
|
389
|
}
|
390
|
rank.setUuid(uuid);
|
391
|
getTermService().save(rank);
|
392
|
}
|
393
|
state.putRank(rank);
|
394
|
}
|
395
|
return rank;
|
396
|
|
397
|
}
|
398
|
|
399
|
/**
|
400
|
* Returns a named area for a given uuid by first . If the named area does not
|
401
|
* @param state
|
402
|
* @param uuid
|
403
|
* @param label
|
404
|
* @param text
|
405
|
* @param labelAbbrev
|
406
|
* @param areaType
|
407
|
* @param level
|
408
|
* @return
|
409
|
*/
|
410
|
protected NamedArea getNamedArea(STATE state, UUID uuid, String label, String text, String labelAbbrev, NamedAreaType areaType, NamedAreaLevel level){
|
411
|
return getNamedArea(state, uuid, label, text, labelAbbrev, areaType, level, null, null);
|
412
|
}
|
413
|
|
414
|
protected NamedArea getNamedArea(STATE state, UUID uuid, String label, String text, String labelAbbrev, NamedAreaType areaType, NamedAreaLevel level, TermVocabulary voc, TermMatchMode matchMode){
|
415
|
return getNamedArea(state, uuid, label, text, labelAbbrev, areaType, level, voc, matchMode, null);
|
416
|
}
|
417
|
|
418
|
|
419
|
protected NamedArea getNamedArea(STATE state, UUID uuid, String label, String text, String labelAbbrev, NamedAreaType areaType, NamedAreaLevel level, TermVocabulary voc, TermMatchMode matchMode,
|
420
|
List<TermVocabulary<NamedArea>> vocabularyPreference){
|
421
|
Class<NamedArea> clazz = NamedArea.class;
|
422
|
if (uuid == null){
|
423
|
uuid = UUID.randomUUID();
|
424
|
}
|
425
|
if (matchMode == null){
|
426
|
matchMode = TermMatchMode.UUID_ONLY;
|
427
|
}
|
428
|
NamedArea namedArea = state.getNamedArea(uuid);
|
429
|
if (namedArea == null){
|
430
|
DefinedTermBase<?> term = getTermService().find(uuid);
|
431
|
namedArea = CdmBase.deproxy(term,NamedArea.class);
|
432
|
|
433
|
if (vocabularyPreference == null){
|
434
|
vocabularyPreference = new ArrayList<TermVocabulary<NamedArea>>();
|
435
|
}
|
436
|
if (vocabularyPreference.isEmpty()){ //add TDWG vocabulary if preferences are empty
|
437
|
vocabularyPreference.add(Country.GERMANY().getVocabulary());
|
438
|
vocabularyPreference.add(TdwgAreaProvider.getAreaByTdwgAbbreviation("GER").getVocabulary());
|
439
|
}
|
440
|
|
441
|
|
442
|
//TODO matching still experimental
|
443
|
if (namedArea == null && (matchMode.equals(TermMatchMode.UUID_LABEL) || matchMode.equals(TermMatchMode.UUID_LABEL_ABBREVLABEL ))){
|
444
|
//TODO test
|
445
|
Pager<NamedArea> areaPager = (Pager)getTermService().findByTitle(clazz, label, null, null, null, null, null, null);
|
446
|
namedArea = findBestMatchingArea(areaPager, uuid, label, text, labelAbbrev, vocabularyPreference);
|
447
|
}
|
448
|
if (namedArea == null && (matchMode.equals(TermMatchMode.UUID_ABBREVLABEL) || matchMode.equals(TermMatchMode.UUID_LABEL_ABBREVLABEL))){
|
449
|
Pager<NamedArea> areaPager = getTermService().findByRepresentationAbbreviation(labelAbbrev, clazz, null, null);
|
450
|
namedArea = findBestMatchingArea(areaPager, uuid, label, text, labelAbbrev, vocabularyPreference);
|
451
|
}
|
452
|
|
453
|
if (namedArea == null){
|
454
|
namedArea = NamedArea.NewInstance(text, label, labelAbbrev);
|
455
|
if (voc == null){
|
456
|
boolean isOrdered = true;
|
457
|
voc = getVocabulary(TermType.NamedArea, uuidUserDefinedNamedAreaVocabulary, "User defined vocabulary for named areas", "User Defined Named Areas", null, null, isOrdered, namedArea);
|
458
|
}
|
459
|
voc.addTerm(namedArea);
|
460
|
namedArea.setType(areaType);
|
461
|
namedArea.setLevel(level);
|
462
|
namedArea.setUuid(uuid);
|
463
|
getTermService().saveOrUpdate(namedArea);
|
464
|
}
|
465
|
state.putNamedArea(namedArea);
|
466
|
}
|
467
|
return namedArea;
|
468
|
}
|
469
|
|
470
|
|
471
|
private NamedArea findBestMatchingArea(Pager<NamedArea> areaPager, UUID uuid, String label, String text, String abbrev, List<TermVocabulary<NamedArea>> vocabularyPreference) {
|
472
|
// TODO preliminary implementation
|
473
|
List<NamedArea> list = areaPager.getRecords();
|
474
|
if (list.size() == 0){
|
475
|
return null;
|
476
|
}else if (list.size() == 1){
|
477
|
return list.get(0);
|
478
|
}else if (list.size() > 1){
|
479
|
List<NamedArea> preferredList = new ArrayList<>();
|
480
|
for (TermVocabulary<NamedArea> voc: vocabularyPreference){
|
481
|
for (NamedArea area : list){
|
482
|
if (voc.equals(area.getVocabulary())){
|
483
|
preferredList.add(area);
|
484
|
}
|
485
|
}
|
486
|
if (preferredList.size() > 0){
|
487
|
break;
|
488
|
}
|
489
|
}
|
490
|
if (preferredList.size() > 1 ){
|
491
|
preferredList = getHighestLevelAreas(preferredList);
|
492
|
}else if (preferredList.size() == 0 ){
|
493
|
preferredList = list;
|
494
|
}
|
495
|
if (preferredList.size() == 1 ){
|
496
|
return preferredList.get(0);
|
497
|
}else if (preferredList.size() > 1 ){
|
498
|
String message = "There is more than 1 matching area for %s, %s, %s. As a preliminary implementation I take the first";
|
499
|
message = String.format(message, label, abbrev, text);
|
500
|
logger.warn(message);
|
501
|
return list.get(0);
|
502
|
}
|
503
|
}
|
504
|
return null;
|
505
|
}
|
506
|
|
507
|
|
508
|
private List<NamedArea> getHighestLevelAreas(List<NamedArea> preferredList) {
|
509
|
List<NamedArea> result = new ArrayList<>();
|
510
|
for (NamedArea area : preferredList){
|
511
|
if (result.isEmpty()){
|
512
|
result.add(area);
|
513
|
}else {
|
514
|
int compare = compareAreaLevel(area, result.get(0));
|
515
|
if (compare > 0){
|
516
|
result = new ArrayList<>();
|
517
|
result.add(area);
|
518
|
}else if (compare == 0){
|
519
|
result.add(area);
|
520
|
}else{
|
521
|
//do nothing
|
522
|
}
|
523
|
}
|
524
|
}
|
525
|
|
526
|
return result;
|
527
|
}
|
528
|
|
529
|
|
530
|
private int compareAreaLevel(NamedArea area1, NamedArea area2) {
|
531
|
NamedAreaLevel level1 = area1.getLevel();
|
532
|
NamedAreaLevel level2 = area2.getLevel();
|
533
|
if (level1 == null){
|
534
|
return (level2 == null)? 0 : 1;
|
535
|
}else if (level2 == null){
|
536
|
return -1;
|
537
|
}else{
|
538
|
return level1.compareTo(level2);
|
539
|
}
|
540
|
}
|
541
|
|
542
|
|
543
|
protected NamedAreaLevel getNamedAreaLevel(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary<NamedAreaLevel> voc){
|
544
|
if (uuid == null){
|
545
|
uuid = UUID.randomUUID();
|
546
|
}
|
547
|
NamedAreaLevel namedAreaLevel = state.getNamedAreaLevel(uuid);
|
548
|
if (namedAreaLevel == null){
|
549
|
//TODO propPath just for testing
|
550
|
List<String> propPath = Arrays.asList("vocabulary");
|
551
|
DefinedTermBase<NamedAreaLevel> term = getTermService().load(uuid, propPath);
|
552
|
namedAreaLevel = CdmBase.deproxy(term, NamedAreaLevel.class);
|
553
|
if (namedAreaLevel == null){
|
554
|
namedAreaLevel = NamedAreaLevel.NewInstance(text, label, labelAbbrev);
|
555
|
if (voc == null){
|
556
|
boolean isOrdered = true;
|
557
|
voc = getVocabulary(TermType.NamedAreaLevel, uuidUserDefinedNamedAreaLevelVocabulary, "User defined vocabulary for named area levels", "User Defined Named Area Levels", null, null, isOrdered, namedAreaLevel);
|
558
|
}
|
559
|
//FIXME only for debugging
|
560
|
Set<NamedAreaLevel> terms = voc.getTerms();
|
561
|
for (NamedAreaLevel level : terms){
|
562
|
TermVocabulary<NamedAreaLevel> levelVoc = level.getVocabulary();
|
563
|
if (levelVoc == null){
|
564
|
logger.error("ONLY FOR DEBUG: Level voc is null");
|
565
|
}else{
|
566
|
logger.info("ONLY FOR DEBUG: Level voc is not null");
|
567
|
}
|
568
|
}
|
569
|
voc.addTerm(namedAreaLevel);
|
570
|
namedAreaLevel.setUuid(uuid);
|
571
|
getTermService().save(namedAreaLevel);
|
572
|
}
|
573
|
state.putNamedAreaLevel(namedAreaLevel);
|
574
|
}
|
575
|
return namedAreaLevel;
|
576
|
}
|
577
|
|
578
|
/**
|
579
|
* Returns a {@link State} if it exists. <code>null</code> otherwise.
|
580
|
* @param state
|
581
|
* @param uuid
|
582
|
* @return {@link State}
|
583
|
*/
|
584
|
protected State getStateTerm(STATE state, UUID uuid){
|
585
|
return getStateTerm(state, uuid, null, null, null, null);
|
586
|
}
|
587
|
|
588
|
|
589
|
/**
|
590
|
* Returns a {@link State} for a given uuid by first checking if the uuid has already been used in this import, if not
|
591
|
* checking if the state exists in the database, if not creating it anew (with vocabulary etc.).
|
592
|
* If label, text and labelAbbrev are all <code>null</code> no state is created.
|
593
|
* @param importState
|
594
|
* @param uuid
|
595
|
* @param label
|
596
|
* @param text
|
597
|
* @param labelAbbrev
|
598
|
* @param voc
|
599
|
* @return
|
600
|
*/
|
601
|
protected State getStateTerm(STATE importState, UUID uuid, String label, String text, String labelAbbrev, OrderedTermVocabulary<State> voc) {
|
602
|
if (uuid == null){
|
603
|
return null;
|
604
|
}
|
605
|
State stateTerm = importState.getStateTerm(uuid);
|
606
|
if (stateTerm == null){
|
607
|
stateTerm = CdmBase.deproxy(getTermService().find(uuid), State.class);
|
608
|
if (stateTerm == null && ! hasNoLabel(label, text, labelAbbrev)){
|
609
|
stateTerm = State.NewInstance(text, label, labelAbbrev);
|
610
|
stateTerm.setUuid(uuid);
|
611
|
if (voc == null){
|
612
|
boolean isOrdered = true;
|
613
|
TermVocabulary<State> orderedVoc = getVocabulary(TermType.State, uuidUserDefinedStateVocabulary, "User defined vocabulary for states used by Categorical Data", "User Defined States", null, null, isOrdered, stateTerm);
|
614
|
voc = CdmBase.deproxy(orderedVoc, OrderedTermVocabulary.class);
|
615
|
}
|
616
|
voc.addTerm(stateTerm);
|
617
|
getTermService().save(stateTerm);
|
618
|
}else if (stateTerm == null){
|
619
|
logger.warn("No label provided for new state with uuid " + uuid);
|
620
|
}
|
621
|
importState.putStateTerm(stateTerm);
|
622
|
}
|
623
|
return stateTerm;
|
624
|
}
|
625
|
|
626
|
/**
|
627
|
* Returns a feature if it exists, null otherwise.
|
628
|
* @see #getFeature(ImportStateBase, UUID, String, String, String, TermVocabulary)
|
629
|
* @param state
|
630
|
* @param uuid
|
631
|
* @return
|
632
|
*/
|
633
|
protected Feature getFeature(STATE state, UUID uuid){
|
634
|
return getFeature(state, uuid, null, null, null, null);
|
635
|
}
|
636
|
|
637
|
/**
|
638
|
* Returns a feature for a given uuid by first checking if the uuid has already been used in this import, if not
|
639
|
* checking if the feature exists in the database, if not creating it anew (with vocabulary etc.).
|
640
|
* If label, text and labelAbbrev are all <code>null</code> no feature is created.
|
641
|
* @param state
|
642
|
* @param uuid
|
643
|
* @param label
|
644
|
* @param text
|
645
|
* @param labelAbbrev
|
646
|
* @return
|
647
|
*/
|
648
|
protected Feature getFeature(STATE state, UUID uuid, String label, String description, String labelAbbrev, TermVocabulary<Feature> voc){
|
649
|
if (uuid == null){
|
650
|
return null;
|
651
|
}
|
652
|
Feature feature = state.getFeature(uuid);
|
653
|
if (feature == null){
|
654
|
feature = (Feature)getTermService().find(uuid);
|
655
|
if (feature == null && ! hasNoLabel(label, description, labelAbbrev)){
|
656
|
feature = Feature.NewInstance(description, label, labelAbbrev);
|
657
|
feature.setUuid(uuid);
|
658
|
feature.setSupportsTextData(true);
|
659
|
// UUID uuidFeatureVoc = UUID.fromString("b187d555-f06f-4d65-9e53-da7c93f8eaa8");
|
660
|
if (voc == null){
|
661
|
boolean isOrdered = false;
|
662
|
voc = getVocabulary(TermType.Feature, uuidUserDefinedFeatureVocabulary, "User defined vocabulary for features", "User Defined Features", null, null, isOrdered, feature);
|
663
|
}
|
664
|
voc.addTerm(feature);
|
665
|
getTermService().save(feature);
|
666
|
}
|
667
|
state.putFeature(feature);
|
668
|
}
|
669
|
return feature;
|
670
|
}
|
671
|
|
672
|
protected DefinedTerm getKindOfUnit(STATE state, UUID uuid, String label, String description, String labelAbbrev, TermVocabulary<DefinedTerm> voc){
|
673
|
if (uuid == null){
|
674
|
uuid = UUID.randomUUID();
|
675
|
}
|
676
|
DefinedTerm unit = state.getKindOfUnit(uuid);
|
677
|
if (unit == null){
|
678
|
unit = (DefinedTerm)getTermService().find(uuid);
|
679
|
if (unit == null && ! hasNoLabel(label, description, labelAbbrev)){
|
680
|
unit = DefinedTerm.NewKindOfUnitInstance(description, label, labelAbbrev);
|
681
|
unit.setUuid(uuid);
|
682
|
if (voc == null){
|
683
|
boolean isOrdered = false;
|
684
|
voc = getVocabulary(TermType.KindOfUnit, uuidUserDefinedKindOfUnitVocabulary, "User defined vocabulary for kind-of-units", "User Defined Measurement kind-of-units", null, null, isOrdered, unit);
|
685
|
}
|
686
|
voc.addTerm(unit);
|
687
|
getTermService().save(unit);
|
688
|
}
|
689
|
state.putKindOfUnit(unit);
|
690
|
}
|
691
|
return unit;
|
692
|
}
|
693
|
|
694
|
/**
|
695
|
* Returns a {@link MeasurementUnit} for a given uuid by first checking if the uuid has already been used in this import, if not
|
696
|
* checking if the {@link MeasurementUnit} exists in the database, if not creating it anew (with vocabulary etc.).
|
697
|
* If label, text and labelAbbrev are all <code>null</code> no {@link MeasurementUnit} is created.
|
698
|
* @param state
|
699
|
* @param uuid
|
700
|
* @param label
|
701
|
* @param text
|
702
|
* @param labelAbbrev
|
703
|
* @return
|
704
|
*/
|
705
|
protected MeasurementUnit getMeasurementUnit(STATE state, UUID uuid, String label, String description, String labelAbbrev, TermVocabulary<MeasurementUnit> voc){
|
706
|
if (uuid == null){
|
707
|
return null;
|
708
|
}
|
709
|
MeasurementUnit unit = state.getMeasurementUnit(uuid);
|
710
|
if (unit == null){
|
711
|
unit = (MeasurementUnit)getTermService().find(uuid);
|
712
|
if (unit == null && ! hasNoLabel(label, description, labelAbbrev)){
|
713
|
unit = MeasurementUnit.NewInstance(description, label, labelAbbrev);
|
714
|
unit.setUuid(uuid);
|
715
|
if (voc == null){
|
716
|
boolean isOrdered = false;
|
717
|
voc = getVocabulary(TermType.MeasurementUnit, uuidUserDefinedMeasurementUnitVocabulary, "User defined vocabulary for measurement units", "User Defined Measurement Units", null, null, isOrdered, unit);
|
718
|
}
|
719
|
voc.addTerm(unit);
|
720
|
getTermService().save(unit);
|
721
|
}
|
722
|
state.putMeasurementUnit(unit);
|
723
|
}
|
724
|
return unit;
|
725
|
}
|
726
|
|
727
|
/**
|
728
|
* Returns a {@link StatisticalMeasure} for a given uuid by first checking if the uuid has already been used in this import, if not
|
729
|
* checking if the {@link StatisticalMeasure} exists in the database, if not creating it anew (with vocabulary etc.).
|
730
|
* If label, text and labelAbbrev are all <code>null</code> no {@link StatisticalMeasure} is created.
|
731
|
* @param state
|
732
|
* @param uuid
|
733
|
* @param label
|
734
|
* @param text
|
735
|
* @param labelAbbrev
|
736
|
* @return
|
737
|
*/
|
738
|
protected StatisticalMeasure getStatisticalMeasure(STATE state, UUID uuid, String label, String description, String labelAbbrev, TermVocabulary<StatisticalMeasure> voc){
|
739
|
if (uuid == null){
|
740
|
return null;
|
741
|
}
|
742
|
StatisticalMeasure statisticalMeasure = state.getStatisticalMeasure(uuid);
|
743
|
if (statisticalMeasure == null){
|
744
|
statisticalMeasure = (StatisticalMeasure)getTermService().find(uuid);
|
745
|
if (statisticalMeasure == null && ! hasNoLabel(label, description, labelAbbrev)){
|
746
|
statisticalMeasure = StatisticalMeasure.NewInstance(description, label, labelAbbrev);
|
747
|
statisticalMeasure.setUuid(uuid);
|
748
|
if (voc == null){
|
749
|
boolean isOrdered = false;
|
750
|
voc = getVocabulary(TermType.StatisticalMeasure, uuidUserDefinedStatisticalMeasureVocabulary, "User defined vocabulary for statistical measures", "User Defined Statistical Measures", null, null, isOrdered, statisticalMeasure);
|
751
|
}
|
752
|
voc.addTerm(statisticalMeasure);
|
753
|
getTermService().save(statisticalMeasure);
|
754
|
}
|
755
|
state.putStatisticalMeasure(statisticalMeasure);
|
756
|
}
|
757
|
return statisticalMeasure;
|
758
|
}
|
759
|
|
760
|
/**
|
761
|
* Returns a {@link Modifier} for a given uuid by first checking if the uuid has already been used in this import, if not
|
762
|
* checking if the {@link Modifier} exists in the database, if not creating it anew (with vocabulary etc.).
|
763
|
* If label, text and labelAbbrev are all <code>null</code> no {@link Modifier} is created.
|
764
|
* @param state
|
765
|
* @param uuid
|
766
|
* @param label
|
767
|
* @param text
|
768
|
* @param labelAbbrev
|
769
|
* @return
|
770
|
*/
|
771
|
protected DefinedTerm getModifier(STATE state, UUID uuid, String label, String description, String labelAbbrev, TermVocabulary<DefinedTerm> voc){
|
772
|
if (uuid == null){
|
773
|
return null;
|
774
|
}
|
775
|
DefinedTerm modifier = state.getModifier(uuid);
|
776
|
if (modifier == null){
|
777
|
modifier = (DefinedTerm)getTermService().find(uuid);
|
778
|
if (modifier == null && ! hasNoLabel(label, description, labelAbbrev)){
|
779
|
modifier = DefinedTerm.NewModifierInstance(description, label, labelAbbrev);
|
780
|
modifier.setUuid(uuid);
|
781
|
if (voc == null){
|
782
|
boolean isOrdered = false;
|
783
|
voc = getVocabulary(TermType.Modifier, uuidUserDefinedModifierVocabulary, "User defined vocabulary for modifier", "User Defined Modifier", null, null, isOrdered, modifier);
|
784
|
}
|
785
|
voc.addTerm(modifier);
|
786
|
getTermService().save(modifier);
|
787
|
}
|
788
|
state.putModifier(modifier);
|
789
|
}
|
790
|
return modifier;
|
791
|
}
|
792
|
|
793
|
/**
|
794
|
* Returns a taxon relationship type for a given uuid by first checking if the uuid has already been used in this import, if not
|
795
|
* checking if the taxon relationship type exists in the database, if not creating it anew (with vocabulary etc.).
|
796
|
* If label, text and labelAbbrev are all <code>null</code> no taxon relationship type is created.
|
797
|
* @param state
|
798
|
* @param uuid
|
799
|
* @param label
|
800
|
* @param text
|
801
|
* @param labelAbbrev
|
802
|
* @return
|
803
|
*/
|
804
|
protected TaxonRelationshipType getTaxonRelationshipType(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary<TaxonRelationshipType> voc){
|
805
|
if (uuid == null){
|
806
|
return null;
|
807
|
}
|
808
|
TaxonRelationshipType relType = state.getTaxonRelationshipType(uuid);
|
809
|
if (relType == null){
|
810
|
relType = (TaxonRelationshipType)getTermService().find(uuid);
|
811
|
if (relType == null && ! hasNoLabel(label, text, labelAbbrev)){
|
812
|
relType = TaxonRelationshipType.NewInstance(text, label, labelAbbrev, false, false);
|
813
|
relType.setUuid(uuid);
|
814
|
if (voc == null){
|
815
|
boolean isOrdered = true;
|
816
|
voc = getVocabulary(TermType.TaxonRelationshipType, uuidUserDefinedTaxonRelationshipTypeVocabulary, "User defined vocabulary for taxon relationship types", "User Defined Taxon Relationship Types", null, null, isOrdered, relType);
|
817
|
}
|
818
|
voc.addTerm(relType);
|
819
|
getTermService().save(relType);
|
820
|
}
|
821
|
state.putTaxonRelationshipType(relType);
|
822
|
}
|
823
|
return relType;
|
824
|
}
|
825
|
|
826
|
private boolean hasNoLabel(String label, String text, String labelAbbrev) {
|
827
|
return label == null && text == null && labelAbbrev == null;
|
828
|
}
|
829
|
|
830
|
protected PresenceAbsenceTerm getPresenceTerm(STATE state, UUID uuid, String label, String text, String labelAbbrev, boolean isAbsenceTerm){
|
831
|
return getPresenceTerm(state, uuid, label, text, labelAbbrev, isAbsenceTerm, null);
|
832
|
}
|
833
|
|
834
|
|
835
|
/**
|
836
|
* Returns a presence term for a given uuid by first ...
|
837
|
* @param state
|
838
|
* @param uuid
|
839
|
* @param label
|
840
|
* @param text
|
841
|
* @param labelAbbrev
|
842
|
* @return
|
843
|
*/
|
844
|
protected PresenceAbsenceTerm getPresenceTerm(STATE state, UUID uuid, String label, String text, String labelAbbrev, boolean isAbsenceTerm, TermVocabulary<PresenceAbsenceTerm> voc){
|
845
|
if (uuid == null){
|
846
|
return null;
|
847
|
}
|
848
|
PresenceAbsenceTerm presenceTerm = state.getPresenceAbsenceTerm(uuid);
|
849
|
if (presenceTerm == null){
|
850
|
presenceTerm = (PresenceAbsenceTerm)getTermService().find(uuid);
|
851
|
if (presenceTerm == null){
|
852
|
presenceTerm = PresenceAbsenceTerm.NewPresenceInstance(text, label, labelAbbrev);
|
853
|
presenceTerm.setUuid(uuid);
|
854
|
presenceTerm.setAbsenceTerm(isAbsenceTerm);
|
855
|
//set vocabulary ; FIXME use another user-defined vocabulary
|
856
|
if (voc == null){
|
857
|
boolean isOrdered = true;
|
858
|
voc = getVocabulary(TermType.PresenceAbsenceTerm, uuidUserDefinedPresenceAbsenceVocabulary, "User defined vocabulary for distribution status", "User Defined Distribution Status", null, null, isOrdered, presenceTerm);
|
859
|
}
|
860
|
voc.addTerm(presenceTerm);
|
861
|
getTermService().save(presenceTerm);
|
862
|
}
|
863
|
state.putPresenceAbsenceTerm(presenceTerm);
|
864
|
}
|
865
|
return presenceTerm;
|
866
|
}
|
867
|
|
868
|
/**
|
869
|
* Returns a language for a given uuid by first ...
|
870
|
* @param state
|
871
|
* @param uuid
|
872
|
* @param label
|
873
|
* @param text
|
874
|
* @param labelAbbrev
|
875
|
* @return
|
876
|
*/
|
877
|
protected Language getLanguage(STATE state, UUID uuid, String label, String text, String labelAbbrev){
|
878
|
return getLanguage(state, uuid, label, text, labelAbbrev, null);
|
879
|
}
|
880
|
|
881
|
protected Language getLanguage(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary voc){
|
882
|
if (uuid == null){
|
883
|
return null;
|
884
|
}
|
885
|
Language language = state.getLanguage(uuid);
|
886
|
if (language == null){
|
887
|
language = (Language)getTermService().find(uuid);
|
888
|
if (language == null){
|
889
|
language = Language.NewInstance(text, label, labelAbbrev);
|
890
|
|
891
|
language.setUuid(uuid);
|
892
|
if (voc == null){
|
893
|
UUID uuidLanguageVoc = UUID.fromString("463a96f1-20ba-4a4c-9133-854c1682bd9b");
|
894
|
boolean isOrdered = false;
|
895
|
voc = getVocabulary(TermType.Language, uuidLanguageVoc, "User defined languages", "User defined languages", "User defined languages", null, isOrdered, language);
|
896
|
}
|
897
|
//set vocabulary ; FIXME use another user-defined vocabulary
|
898
|
|
899
|
voc.addTerm(language);
|
900
|
getTermService().save(language);
|
901
|
}
|
902
|
state.putLanguage(language);
|
903
|
}
|
904
|
return language;
|
905
|
}
|
906
|
|
907
|
|
908
|
/**
|
909
|
* @param uuid
|
910
|
* @return
|
911
|
*
|
912
|
*/
|
913
|
protected <T extends DefinedTermBase> TermVocabulary<T> getVocabulary(TermType termType, UUID uuid, String description, String label, String abbrev, URI termSourceUri, boolean isOrdered, T type) {
|
914
|
List<String> propPath = Arrays.asList(new String[]{"terms"});
|
915
|
TermVocabulary<T> voc = getVocabularyService().load(uuid, propPath);
|
916
|
if (voc == null){
|
917
|
if (isOrdered){
|
918
|
voc = OrderedTermVocabulary.NewInstance(termType, description, label, abbrev, termSourceUri);
|
919
|
}else{
|
920
|
voc = TermVocabulary.NewInstance(termType, description, label, abbrev, termSourceUri);
|
921
|
}
|
922
|
voc.setUuid(uuid);
|
923
|
getVocabularyService().save(voc);
|
924
|
}
|
925
|
return voc;
|
926
|
}
|
927
|
|
928
|
/**
|
929
|
* Adds an orginal source to a sourceable objects (implemented for Identifiable entity and description element.
|
930
|
* If cdmBase is not sourceable nothing happens.
|
931
|
* TODO Move to DbImportBase once this exists.
|
932
|
* TODO also implemented in DbImportObjectCreationMapper (reduce redundance)
|
933
|
* @param rs
|
934
|
* @param cdmBase
|
935
|
* @param dbIdAttribute
|
936
|
* @param namespace
|
937
|
* @param citation
|
938
|
* @throws SQLException
|
939
|
*/
|
940
|
public void addOriginalSource(ICdmBase cdmBase, Object idAttributeValue, String namespace, Reference citation) {
|
941
|
if (cdmBase instanceof ISourceable ){
|
942
|
IOriginalSource source;
|
943
|
ISourceable sourceable = (ISourceable<?>)cdmBase;
|
944
|
Object id = idAttributeValue;
|
945
|
String strId = String.valueOf(id);
|
946
|
String microCitation = null;
|
947
|
OriginalSourceType type = OriginalSourceType.Import;
|
948
|
if (cdmBase instanceof IdentifiableEntity){
|
949
|
source = IdentifiableSource.NewInstance(type, strId, namespace, citation, microCitation);
|
950
|
}else if (cdmBase instanceof DescriptionElementBase){
|
951
|
source = DescriptionElementSource.NewInstance(type, strId, namespace, citation, microCitation);
|
952
|
}else{
|
953
|
logger.warn("ISourceable not beeing identifiable entities or description element base are not yet supported. CdmBase is of type " + cdmBase.getClass().getName() + ". Original source not added.");
|
954
|
return;
|
955
|
}
|
956
|
sourceable.addSource(source);
|
957
|
}else if (cdmBase != null){
|
958
|
logger.warn("Sourced object does not implement ISourceable: " + cdmBase.getClass() + "," + cdmBase.getUuid());
|
959
|
}else{
|
960
|
logger.warn("Sourced object is null");
|
961
|
}
|
962
|
}
|
963
|
|
964
|
/**
|
965
|
* @see #addOriginalSource(CdmBase, Object, String, Reference)
|
966
|
* @param rs
|
967
|
* @param cdmBase
|
968
|
* @param dbIdAttribute
|
969
|
* @param namespace
|
970
|
* @param citation
|
971
|
* @throws SQLException
|
972
|
*/
|
973
|
public void addOriginalSource(ResultSet rs, CdmBase cdmBase, String dbIdAttribute, String namespace, Reference citation) throws SQLException {
|
974
|
Object id = rs.getObject(dbIdAttribute);
|
975
|
addOriginalSource(cdmBase, id, namespace, citation);
|
976
|
}
|
977
|
|
978
|
|
979
|
/**
|
980
|
* If the child taxon is missing genus or species epithet information and the rank is below <i>genus</i>
|
981
|
* or <i>species</i> respectively the according epithets are taken from the parent taxon.
|
982
|
* If the name is an autonym and has no combination author/basionym author the authors are taken from
|
983
|
* the parent.
|
984
|
* @param parentTaxon
|
985
|
* @param childTaxon
|
986
|
*/
|
987
|
protected void fillMissingEpithetsForTaxa(Taxon parentTaxon, Taxon childTaxon) {
|
988
|
if (parentTaxon == null){
|
989
|
logger.warn("Parent taxon is null. Missing name parts can not be taken from parent");
|
990
|
return;
|
991
|
}
|
992
|
INonViralName parentName = parentTaxon.getName();
|
993
|
INonViralName childName = childTaxon.getName();
|
994
|
fillMissingEpithets(parentName, childName);
|
995
|
}
|
996
|
|
997
|
/**
|
998
|
* If the child name is missing genus or species epithet information and the rank is below <i>genus</i>
|
999
|
* or <i>species</i> respectively the according epithets are taken from the parent name.
|
1000
|
* If the name is an autonym and has no combination author/basionym author the authors are taken from
|
1001
|
* the parent.
|
1002
|
* @param parentTaxon
|
1003
|
* @param childTaxon
|
1004
|
*/
|
1005
|
protected void fillMissingEpithets(INonViralName parentName, INonViralName childName) {
|
1006
|
if (StringUtils.isBlank(childName.getGenusOrUninomial()) && childName.getRank().isLower(Rank.GENUS()) ){
|
1007
|
childName.setGenusOrUninomial(parentName.getGenusOrUninomial());
|
1008
|
}
|
1009
|
|
1010
|
if (StringUtils.isBlank(childName.getSpecificEpithet()) && childName.getRank().isLower(Rank.SPECIES()) ){
|
1011
|
childName.setSpecificEpithet(parentName.getSpecificEpithet());
|
1012
|
}
|
1013
|
if (childName.isAutonym() && childName.getCombinationAuthorship() == null && childName.getBasionymAuthorship() == null ){
|
1014
|
childName.setCombinationAuthorship(parentName.getCombinationAuthorship());
|
1015
|
childName.setBasionymAuthorship(parentName.getBasionymAuthorship());
|
1016
|
}
|
1017
|
}
|
1018
|
|
1019
|
/**
|
1020
|
* Returns the taxon description for a taxon. If there are multiple taxon descriptions
|
1021
|
* an arbitrary one is chosen.
|
1022
|
* If no taxon description exists, a new one is created if <code>createNewIfNotExists</code>
|
1023
|
* is <code>true</code>.
|
1024
|
* @param createNewIfNotExists
|
1025
|
* @param isImageGallery if true only taxon description being image galleries are considered.
|
1026
|
* If false only taxon description being no image galleries are considered.
|
1027
|
* @return
|
1028
|
*/
|
1029
|
public TaxonNameDescription getTaxonNameDescription(TaxonName name, boolean isImageGallery, boolean createNewIfNotExists) {
|
1030
|
Reference ref = null;
|
1031
|
return getTaxonNameDescription(name, ref, isImageGallery, createNewIfNotExists);
|
1032
|
}
|
1033
|
|
1034
|
/**
|
1035
|
* Like {@link #getTaxonDescription(Taxon, boolean, boolean)}
|
1036
|
* Only matches a description if the given reference is a source of the description.<BR>
|
1037
|
* If a new description is created the given reference will be added as a source.
|
1038
|
*
|
1039
|
* @see #getTaxonDescription(Taxon, boolean, boolean)
|
1040
|
*/
|
1041
|
public TaxonNameDescription getTaxonNameDescription(TaxonName<?,?> name, Reference ref, boolean isImageGallery, boolean createNewIfNotExists) {
|
1042
|
TaxonNameDescription result = null;
|
1043
|
Set<TaxonNameDescription> descriptions= name.getDescriptions();
|
1044
|
for (TaxonNameDescription description : descriptions){
|
1045
|
if (description.isImageGallery() == isImageGallery){
|
1046
|
if (hasCorrespondingSource(ref, description)){
|
1047
|
result = description;
|
1048
|
break;
|
1049
|
}
|
1050
|
}
|
1051
|
}
|
1052
|
if (result == null && createNewIfNotExists){
|
1053
|
result = TaxonNameDescription.NewInstance(name);
|
1054
|
result.setImageGallery(isImageGallery);
|
1055
|
if (ref != null){
|
1056
|
result.addImportSource(null, null, ref, null);
|
1057
|
}
|
1058
|
}
|
1059
|
return result;
|
1060
|
}
|
1061
|
|
1062
|
/**
|
1063
|
* Returns the taxon description for a taxon. If there are multiple taxon descriptions
|
1064
|
* an arbitrary one is chosen.
|
1065
|
* If no taxon description exists, a new one is created if <code>createNewIfNotExists</code>
|
1066
|
* is <code>true</code>.
|
1067
|
* @param createNewIfNotExists
|
1068
|
* @param isImageGallery if true only taxon description being image galleries are considered.
|
1069
|
* If false only taxon description being no image galleries are considered.
|
1070
|
* @return
|
1071
|
*/
|
1072
|
public TaxonDescription getTaxonDescription(Taxon taxon, boolean isImageGallery, boolean createNewIfNotExists) {
|
1073
|
Reference ref = null;
|
1074
|
return getTaxonDescription(taxon, ref, isImageGallery, createNewIfNotExists);
|
1075
|
}
|
1076
|
|
1077
|
/**
|
1078
|
* Like {@link #getTaxonDescription(Taxon, boolean, boolean)}
|
1079
|
* Only matches a description if the given reference is a source of the description.<BR>
|
1080
|
* If a new description is created the given reference will be added as a source.
|
1081
|
*
|
1082
|
* @see #getTaxonDescription(Taxon, boolean, boolean)
|
1083
|
* @see #getDefaultTaxonDescription(Taxon, boolean, boolean, Reference)
|
1084
|
*/
|
1085
|
public TaxonDescription getTaxonDescription(Taxon taxon, Reference ref, boolean isImageGallery,
|
1086
|
boolean createNewIfNotExists) {
|
1087
|
TaxonDescription result = null;
|
1088
|
Set<TaxonDescription> descriptions= taxon.getDescriptions();
|
1089
|
for (TaxonDescription description : descriptions){
|
1090
|
if (description.isImageGallery() == isImageGallery){
|
1091
|
if (hasCorrespondingSource(ref, description)){
|
1092
|
result = description;
|
1093
|
break;
|
1094
|
}
|
1095
|
}
|
1096
|
}
|
1097
|
if (result == null && createNewIfNotExists){
|
1098
|
result = TaxonDescription.NewInstance(taxon);
|
1099
|
result.setImageGallery(isImageGallery);
|
1100
|
if (ref != null){
|
1101
|
result.addImportSource(null, null, ref, null);
|
1102
|
}
|
1103
|
}
|
1104
|
return result;
|
1105
|
}
|
1106
|
|
1107
|
/**
|
1108
|
* Returns the default taxon description. If no default taxon description exists,
|
1109
|
* a new one is created, the default flag is set to true and, if a source is passed,
|
1110
|
* it is added to the new description. Otherwise source has no influence.
|
1111
|
* @param taxon
|
1112
|
* @param isImageGallery
|
1113
|
* @param createNewIfNotExists
|
1114
|
* @param source
|
1115
|
* @return the default description
|
1116
|
* @see #getTaxonDescription(Taxon, Reference, boolean, boolean)
|
1117
|
*/
|
1118
|
public TaxonDescription getDefaultTaxonDescription(Taxon taxon, boolean isImageGallery,
|
1119
|
boolean createNewIfNotExists, Reference source) {
|
1120
|
TaxonDescription result = null;
|
1121
|
Set<TaxonDescription> descriptions= taxon.getDescriptions();
|
1122
|
for (TaxonDescription description : descriptions){
|
1123
|
if (description.isImageGallery() == isImageGallery){
|
1124
|
if (description.isDefault()){
|
1125
|
result = description;
|
1126
|
break;
|
1127
|
}
|
1128
|
}
|
1129
|
}
|
1130
|
if (result == null && createNewIfNotExists){
|
1131
|
result = TaxonDescription.NewInstance(taxon);
|
1132
|
result.setImageGallery(isImageGallery);
|
1133
|
result.setDefault(true);
|
1134
|
if (source != null){
|
1135
|
result.addImportSource(null, null, source, null);
|
1136
|
}
|
1137
|
}
|
1138
|
return result;
|
1139
|
}
|
1140
|
|
1141
|
/**
|
1142
|
* Returns the taxon description with marked as <code>true</code> with the given marker type.
|
1143
|
* If createNewIfNotExists a new description is created if it does not yet exist.
|
1144
|
* For the new description the source and the title are set if not <code>null</code>.
|
1145
|
* @param taxon
|
1146
|
* @param markerType
|
1147
|
* @param isImageGallery
|
1148
|
* @param createNewIfNotExists
|
1149
|
* @param source
|
1150
|
* @param title
|
1151
|
* @return the existing or new taxon description
|
1152
|
*/
|
1153
|
public TaxonDescription getMarkedTaxonDescription(Taxon taxon, MarkerType markerType, boolean isImageGallery,
|
1154
|
boolean createNewIfNotExists, Reference source, String title) {
|
1155
|
TaxonDescription result = null;
|
1156
|
Set<TaxonDescription> descriptions= taxon.getDescriptions();
|
1157
|
for (TaxonDescription description : descriptions){
|
1158
|
if (description.isImageGallery() == isImageGallery){
|
1159
|
if (description.hasMarker(markerType, true)){
|
1160
|
result = description;
|
1161
|
break;
|
1162
|
}
|
1163
|
}
|
1164
|
}
|
1165
|
if (result == null && createNewIfNotExists){
|
1166
|
result = TaxonDescription.NewInstance(taxon);
|
1167
|
result.setImageGallery(isImageGallery);
|
1168
|
result.addMarker(Marker.NewInstance(markerType, true));
|
1169
|
if (source != null){
|
1170
|
result.addImportSource(null, null, source, null);
|
1171
|
}
|
1172
|
if (isNotBlank(title)){
|
1173
|
result.setTitleCache(title, true);
|
1174
|
}
|
1175
|
}
|
1176
|
return result;
|
1177
|
}
|
1178
|
|
1179
|
|
1180
|
/**
|
1181
|
* Returns the {@link SpecimenDescription specimen description} for a {@link SpecimenOrObservationBase specimen or observation}.
|
1182
|
* If there are multiple specimen descriptions an arbitrary one is chosen.
|
1183
|
* If no specimen description exists, a new one is created if <code>createNewIfNotExists</code> is <code>true</code>.
|
1184
|
* @param createNewIfNotExists
|
1185
|
* @param isImageGallery if true only specimen description being image galleries are considered.
|
1186
|
* If false only specimen description being no image galleries are considered.
|
1187
|
* @return
|
1188
|
*/
|
1189
|
public SpecimenDescription getSpecimenDescription(SpecimenOrObservationBase specimen, boolean isImageGallery, boolean createNewIfNotExists) {
|
1190
|
Reference ref = null;
|
1191
|
return getSpecimenDescription(specimen, ref, isImageGallery, createNewIfNotExists);
|
1192
|
}
|
1193
|
|
1194
|
/**
|
1195
|
* Like {@link #getSpecimenDescription(SpecimenOrObservationBase, boolean, boolean)}
|
1196
|
* Only matches a description if the given reference is a source of the description.<BR>
|
1197
|
* If a new description is created the given reference will be added as a source.
|
1198
|
*
|
1199
|
* @see #getTaxonDescription(Taxon, boolean, boolean)
|
1200
|
*/
|
1201
|
public SpecimenDescription getSpecimenDescription(SpecimenOrObservationBase specimen, Reference ref, boolean isImageGallery, boolean createNewIfNotExists) {
|
1202
|
SpecimenDescription result = null;
|
1203
|
Set<SpecimenDescription> descriptions= specimen.getDescriptions();
|
1204
|
for (SpecimenDescription description : descriptions){
|
1205
|
if (description.isImageGallery() == isImageGallery){
|
1206
|
if (hasCorrespondingSource(ref, description)){
|
1207
|
result = description;
|
1208
|
break;
|
1209
|
}
|
1210
|
}
|
1211
|
}
|
1212
|
if (result == null && createNewIfNotExists){
|
1213
|
result = SpecimenDescription.NewInstance(specimen);
|
1214
|
result.setImageGallery(isImageGallery);
|
1215
|
if (ref != null){
|
1216
|
result.addImportSource(null, null, ref, null);
|
1217
|
}
|
1218
|
}
|
1219
|
return result;
|
1220
|
}
|
1221
|
|
1222
|
|
1223
|
/**
|
1224
|
* Returns the textdata that holds general information about a feature for a taxon description.
|
1225
|
* This is mainly necessary for descriptions that have more than one description element for
|
1226
|
* a given feature such as 'distribution', 'description' or 'common name'. It may also hold
|
1227
|
* for hierarchical features where no description element exists for a higher hierarchy level.
|
1228
|
* Example: the description feature has subfeatures. But some information like authorship, figures,
|
1229
|
* sources need to be added to the description itself.
|
1230
|
* Currently a feature placeholder is marked by a marker of type 'feature placeholder'. Maybe in future
|
1231
|
* there will be a boolean marker in the TextData class itself.
|
1232
|
*
|
1233
|
* @param state
|
1234
|
* @param feature
|
1235
|
* @param taxon
|
1236
|
* @param ref
|
1237
|
* @param createIfNotExists
|
1238
|
* @return
|
1239
|
*/
|
1240
|
protected TextData getFeaturePlaceholder(STATE state, DescriptionBase<?> description, Feature feature, boolean createIfNotExists) {
|
1241
|
UUID featurePlaceholderUuid = MarkupTransformer.uuidMarkerFeaturePlaceholder;
|
1242
|
for (DescriptionElementBase element : description.getElements()){
|
1243
|
if (element.isInstanceOf(TextData.class)){
|
1244
|
TextData textData = CdmBase.deproxy(element, TextData.class);
|
1245
|
if (textData.getFeature() == null || ! textData.getFeature().equals(feature)){
|
1246
|
continue;
|
1247
|
}
|
1248
|
for (Marker marker : textData.getMarkers()){
|
1249
|
MarkerType markerType = marker.getMarkerType();
|
1250
|
if (markerType != null &&
|
1251
|
markerType.getUuid().equals(featurePlaceholderUuid) &&
|
1252
|
marker.getValue() == true){
|
1253
|
return textData;
|
1254
|
}
|
1255
|
}
|
1256
|
}
|
1257
|
}
|
1258
|
if (createIfNotExists){
|
1259
|
TextData newPlaceholder = TextData.NewInstance(feature);
|
1260
|
MarkerType placeholderMarkerType = getMarkerType(state, featurePlaceholderUuid, "Feature Placeholder", "Feature Placeholder", null);
|
1261
|
Marker marker = Marker.NewInstance(placeholderMarkerType, true);
|
1262
|
newPlaceholder.addMarker(marker);
|
1263
|
description.addElement(newPlaceholder);
|
1264
|
return newPlaceholder;
|
1265
|
}else{
|
1266
|
return null;
|
1267
|
}
|
1268
|
}
|
1269
|
|
1270
|
|
1271
|
|
1272
|
/**
|
1273
|
* Returns true, if this description has a source with a citation equal to the given reference.
|
1274
|
* Returns true if the given reference is null.
|
1275
|
* @param ref
|
1276
|
* @param description
|
1277
|
*/
|
1278
|
private boolean hasCorrespondingSource(Reference ref, DescriptionBase<?> description) {
|
1279
|
if (ref != null){
|
1280
|
for (IdentifiableSource source : description.getSources()){
|
1281
|
if (ref.equals(source.getCitation())){
|
1282
|
return true;
|
1283
|
}
|
1284
|
}
|
1285
|
return false;
|
1286
|
}
|
1287
|
return true;
|
1288
|
|
1289
|
}
|
1290
|
|
1291
|
|
1292
|
/**
|
1293
|
* Returns the accepted taxon of a {@link TaxonBase taxon base}. <BR>
|
1294
|
* If taxonBase is of type taxon the same object is returned. If taxonBase is of type
|
1295
|
* synonym the accepted taxon is returned if one exists. If no accepted taxon exists
|
1296
|
* <code>null</code> is returned. If multiple accepted taxa exist the one taxon with the
|
1297
|
* same secundum reference is returned. If no such single taxon exists an
|
1298
|
* {@link IllegalStateException illegal state exception} is thrown.
|
1299
|
* @param taxonBase
|
1300
|
* @return
|
1301
|
*/
|
1302
|
protected Taxon getAcceptedTaxon(TaxonBase<?> taxonBase) {
|
1303
|
if (taxonBase == null){
|
1304
|
return null;
|
1305
|
}else if(taxonBase.isInstanceOf(Taxon.class)){
|
1306
|
return CdmBase.deproxy(taxonBase, Taxon.class);
|
1307
|
}else if(taxonBase.isInstanceOf(Synonym.class)){
|
1308
|
Synonym synonym = CdmBase.deproxy(taxonBase, Synonym.class);
|
1309
|
Taxon acceptedTaxon = synonym.getAcceptedTaxon();
|
1310
|
return acceptedTaxon;
|
1311
|
}else{
|
1312
|
throw new IllegalStateException("Unknown TaxonBase subclass: " + taxonBase.getClass().getName());
|
1313
|
}
|
1314
|
}
|
1315
|
|
1316
|
protected Media getImageMedia(String uriString, boolean readMediaData) throws MalformedURLException {
|
1317
|
return getImageMedia(uriString, null, readMediaData);
|
1318
|
}
|
1319
|
|
1320
|
/**
|
1321
|
* Creates
|
1322
|
* @param uriString
|
1323
|
* @param readDataFromUrl
|
1324
|
* @see #READ_MEDIA_DATA
|
1325
|
* @return
|
1326
|
* @throws MalformedURLException
|
1327
|
*/
|
1328
|
protected Media getImageMedia(String uriString, String uriStrThumb, boolean readMediaData) throws MalformedURLException {
|
1329
|
if( uriString == null){
|
1330
|
return null;
|
1331
|
} else {
|
1332
|
uriString = uriString.replace(" ", "%20"); //replace whitespace
|
1333
|
try {
|
1334
|
ImageInfo imageInfo = null;
|
1335
|
URI uri = new URI(uriString);
|
1336
|
|
1337
|
try {
|
1338
|
if (readMediaData){
|
1339
|
logger.info("Read media data from: " + uri);
|
1340
|
imageInfo = ImageInfo.NewInstance(uri, 0);
|
1341
|
}
|
1342
|
} catch (Exception e) {
|
1343
|
String message = "An error occurred when trying to read image meta data for " + uri.toString() + ": " + e.getMessage();
|
1344
|
logger.warn(message);
|
1345
|
fireWarningEvent(message, "unknown location", 2, 0);
|
1346
|
}
|
1347
|
ImageFile imageFile = ImageFile.NewInstance(uri, null, imageInfo);
|
1348
|
|
1349
|
MediaRepresentation representation = MediaRepresentation.NewInstance();
|
1350
|
|
1351
|
if(imageInfo != null){
|
1352
|
representation.setMimeType(imageInfo.getMimeType());
|
1353
|
representation.setSuffix(imageInfo.getSuffix());
|
1354
|
}
|
1355
|
representation.addRepresentationPart(imageFile);
|
1356
|
Media media = Media.NewInstance();
|
1357
|
media.addRepresentation(representation);
|
1358
|
|
1359
|
if (uriStrThumb != null){
|
1360
|
ImageInfo imageInfoThumb = null;
|
1361
|
uriStrThumb = uriStrThumb.replace(" ", "%20"); //replace whitespace
|
1362
|
URI uriThumb = new URI(uriStrThumb);
|
1363
|
try {
|
1364
|
if (readMediaData){
|
1365
|
logger.info("Read media data from: " + uriThumb);
|
1366
|
imageInfoThumb = ImageInfo.NewInstance(uriThumb, 0);
|
1367
|
}
|
1368
|
} catch (Exception e) {
|
1369
|
String message = "An error occurred when trying to read image meta data for " + uriThumb.toString() + ": " + e.getMessage();
|
1370
|
logger.warn(message);
|
1371
|
fireWarningEvent(message, "unknown location", 2, 0);
|
1372
|
}
|
1373
|
|
1374
|
ImageFile imageFileFhumb = ImageFile.NewInstance(uriThumb, null, imageInfoThumb);
|
1375
|
MediaRepresentation reprThumb = MediaRepresentation.NewInstance();
|
1376
|
if(imageInfoThumb != null){
|
1377
|
reprThumb.setMimeType(imageInfoThumb.getMimeType());
|
1378
|
reprThumb.setSuffix(imageInfoThumb.getSuffix());
|
1379
|
}
|
1380
|
reprThumb.addRepresentationPart(imageFileFhumb);
|
1381
|
media.addRepresentation(reprThumb);
|
1382
|
}
|
1383
|
|
1384
|
return media;
|
1385
|
} catch (URISyntaxException e1) {
|
1386
|
String message = "An URISyntaxException occurred when trying to create uri from multimedia objcet string: " + uriString;
|
1387
|
logger.warn(message);
|
1388
|
fireWarningEvent(message, "unknown location", 4, 0);
|
1389
|
return null;
|
1390
|
}
|
1391
|
}
|
1392
|
}
|
1393
|
|
1394
|
|
1395
|
/**
|
1396
|
* Retrieves an Integer value from a result set. If the value is NULL null is returned.
|
1397
|
* ResultSet.getInt() returns 0 therefore we need a special handling for this case.
|
1398
|
* @param rs
|
1399
|
* @param columnName
|
1400
|
* @return
|
1401
|
* @throws SQLException
|
1402
|
*/
|
1403
|
protected Integer nullSafeInt(ResultSet rs, String columnName) throws SQLException {
|
1404
|
Object intObject = rs.getObject(columnName);
|
1405
|
if (intObject == null){
|
1406
|
return null;
|
1407
|
}else{
|
1408
|
return Integer.valueOf(intObject.toString());
|
1409
|
}
|
1410
|
}
|
1411
|
|
1412
|
protected Boolean nullSafeBoolean(ResultSet rs, String columnName) throws SQLException {
|
1413
|
Object bitObject = rs.getObject(columnName);
|
1414
|
if (bitObject == null){
|
1415
|
return null;
|
1416
|
}else{
|
1417
|
return Boolean.valueOf(bitObject.toString());
|
1418
|
}
|
1419
|
}
|
1420
|
|
1421
|
protected Double nullSafeDouble(ResultSet rs, String columnName) throws SQLException {
|
1422
|
Object doubleObject = rs.getObject(columnName);
|
1423
|
if (doubleObject == null){
|
1424
|
return null;
|
1425
|
}else{
|
1426
|
return Double.valueOf(doubleObject.toString());
|
1427
|
}
|
1428
|
}
|
1429
|
|
1430
|
protected Float nullSafeFloat(ResultSet rs, String columnName) throws SQLException {
|
1431
|
Object doubleObject = rs.getObject(columnName);
|
1432
|
if (doubleObject == null){
|
1433
|
return null;
|
1434
|
}else{
|
1435
|
return Float.valueOf(doubleObject.toString());
|
1436
|
}
|
1437
|
}
|
1438
|
|
1439
|
|
1440
|
/**
|
1441
|
* Returns <code>null</code> for all blank strings. Identity function otherwise.
|
1442
|
* @param str
|
1443
|
* @return
|
1444
|
*/
|
1445
|
protected String NB(String str) {
|
1446
|
if (StringUtils.isBlank(str)){
|
1447
|
return null;
|
1448
|
}else{
|
1449
|
return str;
|
1450
|
}
|
1451
|
}
|
1452
|
|
1453
|
@Override
|
1454
|
public byte[] getByteArray() {
|
1455
|
// TODO Auto-generated method stub
|
1456
|
return null;
|
1457
|
}
|
1458
|
|
1459
|
public static TeamOrPersonBase<?> parseAuthorString(String authorName){
|
1460
|
TeamOrPersonBase<?> author = null;
|
1461
|
String[] teamMembers = authorName.split(authorSeparator);
|
1462
|
String lastMember;
|
1463
|
String[] lastMembers;
|
1464
|
Person teamMember;
|
1465
|
if (teamMembers.length>1){
|
1466
|
lastMember = teamMembers[teamMembers.length -1];
|
1467
|
lastMembers = lastMember.split(lastAuthorSeparator);
|
1468
|
teamMembers[teamMembers.length -1] = "";
|
1469
|
author = Team.NewInstance();
|
1470
|
for(String member:teamMembers){
|
1471
|
if (!member.equals("")){
|
1472
|
teamMember = Person.NewInstance();
|
1473
|
teamMember.setTitleCache(member, true);
|
1474
|
((Team)author).addTeamMember(teamMember);
|
1475
|
}
|
1476
|
}
|
1477
|
if (lastMembers != null){
|
1478
|
for(String member:lastMembers){
|
1479
|
teamMember = Person.NewInstance();
|
1480
|
teamMember.setTitleCache(member, true);
|
1481
|
((Team)author).addTeamMember(teamMember);
|
1482
|
}
|
1483
|
}
|
1484
|
|
1485
|
} else {
|
1486
|
teamMembers = authorName.split(lastAuthorSeparator);
|
1487
|
if (teamMembers.length>1){
|
1488
|
author = Team.NewInstance();
|
1489
|
for(String member:teamMembers){
|
1490
|
teamMember = Person.NewInstance();
|
1491
|
teamMember.setTitleCache(member, true);
|
1492
|
((Team)author).addTeamMember(teamMember);
|
1493
|
|
1494
|
}
|
1495
|
}else{
|
1496
|
author = Person.NewInstance();
|
1497
|
author.setTitleCache(authorName, true);
|
1498
|
}
|
1499
|
}
|
1500
|
author.getTitleCache();
|
1501
|
return author;
|
1502
|
}
|
1503
|
|
1504
|
|
1505
|
}
|