2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.io
.common
;
12 import java
.net
.MalformedURLException
;
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
;
21 import java
.util
.UUID
;
23 import org
.apache
.commons
.lang
.StringUtils
;
24 import org
.apache
.log4j
.Logger
;
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
.IOriginalSource
;
40 import eu
.etaxonomy
.cdm
.model
.common
.ISourceable
;
41 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
42 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableSource
;
43 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
44 import eu
.etaxonomy
.cdm
.model
.common
.Marker
;
45 import eu
.etaxonomy
.cdm
.model
.common
.MarkerType
;
46 import eu
.etaxonomy
.cdm
.model
.common
.OrderedTermVocabulary
;
47 import eu
.etaxonomy
.cdm
.model
.common
.OriginalSourceType
;
48 import eu
.etaxonomy
.cdm
.model
.common
.TermType
;
49 import eu
.etaxonomy
.cdm
.model
.common
.TermVocabulary
;
50 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionBase
;
51 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
52 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementSource
;
53 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
54 import eu
.etaxonomy
.cdm
.model
.description
.MeasurementUnit
;
55 import eu
.etaxonomy
.cdm
.model
.description
.PresenceAbsenceTerm
;
56 import eu
.etaxonomy
.cdm
.model
.description
.SpecimenDescription
;
57 import eu
.etaxonomy
.cdm
.model
.description
.State
;
58 import eu
.etaxonomy
.cdm
.model
.description
.StatisticalMeasure
;
59 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
60 import eu
.etaxonomy
.cdm
.model
.description
.TaxonNameDescription
;
61 import eu
.etaxonomy
.cdm
.model
.description
.TextData
;
62 import eu
.etaxonomy
.cdm
.model
.location
.Country
;
63 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
64 import eu
.etaxonomy
.cdm
.model
.location
.NamedAreaLevel
;
65 import eu
.etaxonomy
.cdm
.model
.location
.NamedAreaType
;
66 import eu
.etaxonomy
.cdm
.model
.location
.ReferenceSystem
;
67 import eu
.etaxonomy
.cdm
.model
.media
.ImageFile
;
68 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
69 import eu
.etaxonomy
.cdm
.model
.media
.MediaRepresentation
;
70 import eu
.etaxonomy
.cdm
.model
.name
.INonViralName
;
71 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
72 import eu
.etaxonomy
.cdm
.model
.name
.RankClass
;
73 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
74 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
75 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
76 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
77 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
78 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
79 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
80 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationshipType
;
86 public abstract class CdmImportBase
<CONFIG
extends IImportConfigurator
, STATE
extends ImportStateBase
> extends CdmIoBase
<STATE
> implements ICdmImport
<CONFIG
, STATE
>{
87 private static final long serialVersionUID
= 8730012744209195616L;
89 private static Logger logger
= Logger
.getLogger(CdmImportBase
.class);
91 protected static final boolean CREATE
= true;
92 protected static final boolean IMAGE_GALLERY
= true;
93 protected static final boolean READ_MEDIA_DATA
= true;
95 public static final UUID uuidUserDefinedNamedAreaLevelVocabulary
= UUID
.fromString("255144da-8d95-457e-a327-9752a8f85e5a");
96 public static final UUID uuidUserDefinedNamedAreaVocabulary
= UUID
.fromString("b2238399-a3af-4f6d-b7eb-ff5d0899bf1b");
97 public static final UUID uuidUserDefinedExtensionTypeVocabulary
= UUID
.fromString("e28c1394-1be8-4847-8b81-ab44eb6d5bc8");
98 public static final UUID uuidUserDefinedIdentifierTypeVocabulary
= UUID
.fromString("194b173b-e2c8-49f1-bbfa-d5d51556cf68");
99 public static final UUID uuidUserDefinedReferenceSystemVocabulary
= UUID
.fromString("467591a3-10b4-4bf1-9239-f06ece33e90a");
100 public static final UUID uuidUserDefinedFeatureVocabulary
= UUID
.fromString("fe5fccb3-a2f2-4b97-b199-6e2743cf1627");
101 public static final UUID uuidUserDefinedMeasurementUnitVocabulary
= UUID
.fromString("d5e72bb7-f312-4080-bb86-c695d04a6e66");
102 public static final UUID uuidUserDefinedStatisticalMeasureVocabulary
= UUID
.fromString("62a89836-c730-4b4f-a904-3d859dbfc400");
103 public static final UUID uuidUserDefinedStateVocabulary
= UUID
.fromString("f7cddb49-8392-4db1-8640-65b48a0e6d13");
104 public static final UUID uuidUserDefinedTaxonRelationshipTypeVocabulary
= UUID
.fromString("31a324dc-408d-4877-891f-098db21744c6");
105 public static final UUID uuidUserDefinedAnnotationTypeVocabulary
= UUID
.fromString("cd9ecdd2-9cae-4890-9032-ad83293ae883");
106 public static final UUID uuidUserDefinedMarkerTypeVocabulary
= UUID
.fromString("5f02a261-fd7d-4fce-bbe4-21472de8cd51");
107 public static final UUID uuidUserDefinedRankVocabulary
= UUID
.fromString("4dc57931-38e2-46c3-974d-413b087646ba");
108 public static final UUID uuidUserDefinedPresenceAbsenceVocabulary
= UUID
.fromString("6b8a2581-1471-4ea6-b8ad-b2d931cfbc23");
110 public static final UUID uuidUserDefinedModifierVocabulary
= UUID
.fromString("2a8b3838-3a95-49ea-9ab2-3049614b5884");
111 public static final UUID uuidUserDefinedKindOfUnitVocabulary
= UUID
.fromString("e7c5deb2-f485-4a66-9104-0c5398efd481");
115 private static final String UuidOnly
= "UUIDOnly";
116 private static final String UuidLabel
= "UUID or label";
117 private static final String UuidLabelAbbrev
= "UUID, label or abbreviation";
118 private static final String UuidAbbrev
= "UUID or abbreviation";
120 private final static String authorSeparator
= ", ";
121 private final static String lastAuthorSeparator
= " & ";
123 public enum TermMatchMode
{
124 UUID_ONLY(0, UuidOnly
)
125 ,UUID_LABEL(1, UuidLabel
)
126 ,UUID_LABEL_ABBREVLABEL(2, UuidLabelAbbrev
)
127 ,UUID_ABBREVLABEL(3, UuidAbbrev
)
131 private final int id
;
132 private final String representation
;
133 private TermMatchMode(int id
, String representation
){
135 this.representation
= representation
;
140 public String
getRepresentation() {
141 return representation
;
143 public TermMatchMode
valueOf(int id
){
145 case 0: return UUID_ONLY
;
146 case 1: return UUID_LABEL
;
147 case 2: return UUID_LABEL_ABBREVLABEL
;
148 case 3: return UUID_ABBREVLABEL
;
149 default: return UUID_ONLY
;
156 protected Classification
makeTree(STATE state
, Reference reference
){
157 String treeName
= "Classification (Import)";
158 if (reference
!= null && StringUtils
.isNotBlank(reference
.getTitleCache())){
159 treeName
= reference
.getTitleCache();
161 Classification tree
= Classification
.NewInstance(treeName
);
162 tree
.setReference(reference
);
165 // use defined uuid for first tree
166 CONFIG config
= (CONFIG
)state
.getConfig();
167 if (state
.countTrees() < 1 ){
168 tree
.setUuid(config
.getClassificationUuid());
170 getClassificationService().save(tree
);
171 state
.putTree(reference
, tree
);
177 * Alternative memory saving method variant of
178 * {@link #makeTree(STATE state, Reference ref)} which stores only the
179 * UUID instead of the full tree in the <code>ImportStateBase</code> by
180 * using <code>state.putTreeUuid(ref, tree);</code>
186 protected Classification
makeTreeMemSave(STATE state
, Reference ref
){
187 String treeName
= "Classification (Import)";
188 if (ref
!= null && StringUtils
.isNotBlank(ref
.getTitleCache())){
189 treeName
= ref
.getTitleCache();
191 Classification tree
= Classification
.NewInstance(treeName
);
192 tree
.setReference(ref
);
195 // use defined uuid for first tree
196 CONFIG config
= (CONFIG
)state
.getConfig();
197 if (state
.countTrees() < 1 ){
198 tree
.setUuid(config
.getClassificationUuid());
200 getClassificationService().save(tree
);
201 state
.putTreeUuid(ref
, tree
);
208 protected ExtensionType
getExtensionType(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
){
209 return getExtensionType(state
, uuid
, label
, text
, labelAbbrev
, null);
211 protected ExtensionType
getExtensionType(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, TermVocabulary
<ExtensionType
> voc
){
213 uuid
= UUID
.randomUUID();
215 ExtensionType extensionType
= state
.getExtensionType(uuid
);
216 if (extensionType
== null){
217 extensionType
= (ExtensionType
)getTermService().find(uuid
);
218 if (extensionType
== null){
219 extensionType
= ExtensionType
.NewInstance(text
, label
, labelAbbrev
);
220 extensionType
.setUuid(uuid
);
222 boolean isOrdered
= false;
223 voc
= getVocabulary(TermType
.ExtensionType
, uuidUserDefinedExtensionTypeVocabulary
, "User defined vocabulary for extension types", "User Defined Extension Types", null, null, isOrdered
, extensionType
);
225 voc
.addTerm(extensionType
);
226 getTermService().saveOrUpdate(extensionType
);
228 state
.putExtensionType(extensionType
);
230 return extensionType
;
233 protected DefinedTerm
getIdentiferType(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, TermVocabulary
<DefinedTerm
> voc
){
235 uuid
= UUID
.randomUUID();
237 DefinedTerm identifierType
= state
.getIdentifierType(uuid
);
238 if (identifierType
== null){
239 identifierType
= (DefinedTerm
)getTermService().find(uuid
);
240 if (identifierType
== null){
241 identifierType
= DefinedTerm
.NewIdentifierTypeInstance(text
, label
, labelAbbrev
);
242 identifierType
.setUuid(uuid
);
244 boolean isOrdered
= false;
245 voc
= getVocabulary(TermType
.IdentifierType
, uuidUserDefinedIdentifierTypeVocabulary
, "User defined vocabulary for identifier types", "User Defined Identifier Types", null, null, isOrdered
, identifierType
);
247 voc
.addTerm(identifierType
);
248 getTermService().saveOrUpdate(identifierType
);
250 state
.putIdentifierType(identifierType
);
252 return identifierType
;
256 protected MarkerType
getMarkerType(STATE state
, String keyString
) {
257 IInputTransformer transformer
= state
.getTransformer();
258 MarkerType markerType
= null;
260 markerType
= transformer
.getMarkerTypeByKey(keyString
);
261 } catch (UndefinedTransformerMethodException e
) {
262 logger
.info("getMarkerTypeByKey not yet implemented for this import");
264 if (markerType
== null ){
267 uuid
= transformer
.getMarkerTypeUuid(keyString
);
268 return getMarkerType(state
, uuid
, keyString
, keyString
, keyString
);
269 } catch (UndefinedTransformerMethodException e
) {
270 logger
.warn("getMarkerTypeUuid not yet implemented for this import");
276 protected MarkerType
getMarkerType(STATE state
, UUID uuid
, String label
, String description
, String labelAbbrev
){
277 return getMarkerType(state
, uuid
, label
, description
, labelAbbrev
, null, null);
280 protected MarkerType
getMarkerType(STATE state
, UUID uuid
, String label
, String description
, String labelAbbrev
, TermVocabulary
<MarkerType
> voc
){
281 return this.getMarkerType(state
, uuid
, label
, description
, labelAbbrev
, voc
, null);
285 protected MarkerType
getMarkerType(STATE state
, UUID uuid
, String label
, String description
, String labelAbbrev
, TermVocabulary
<MarkerType
> voc
, Language language
){
287 uuid
= UUID
.randomUUID();
289 MarkerType markerType
= state
.getMarkerType(uuid
);
290 if (markerType
== null){
291 markerType
= (MarkerType
)getTermService().find(uuid
);
292 if (markerType
== null){
293 markerType
= MarkerType
.NewInstance(description
, label
, labelAbbrev
);
294 if (language
!= null){
295 markerType
.getRepresentations().iterator().next().setLanguage(language
);
297 markerType
.setUuid(uuid
);
299 boolean isOrdered
= false;
300 voc
= getVocabulary(TermType
.MarkerType
, uuidUserDefinedMarkerTypeVocabulary
, "User defined vocabulary for marker types", "User Defined Marker Types", null, null, isOrdered
, markerType
);
302 voc
.addTerm(markerType
);
303 getTermService().save(markerType
);
305 state
.putMarkerType(markerType
);
310 protected AnnotationType
getAnnotationType(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, TermVocabulary
<AnnotationType
> voc
){
312 uuid
= UUID
.randomUUID();
314 AnnotationType annotationType
= state
.getAnnotationType(uuid
);
315 if (annotationType
== null){
316 annotationType
= (AnnotationType
)getTermService().find(uuid
);
317 if (annotationType
== null){
318 annotationType
= AnnotationType
.NewInstance(label
, text
, labelAbbrev
);
319 annotationType
.setUuid(uuid
);
321 boolean isOrdered
= false;
322 voc
= getVocabulary(TermType
.AnnotationType
, uuidUserDefinedAnnotationTypeVocabulary
, "User defined vocabulary for annotation types", "User Defined Annotation Types", null, null, isOrdered
, annotationType
);
325 voc
.addTerm(annotationType
);
326 getTermService().save(annotationType
);
328 state
.putAnnotationType(annotationType
);
330 return annotationType
;
334 protected ReferenceSystem
getReferenceSystem(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, TermVocabulary voc
){
336 uuid
= UUID
.randomUUID();
338 ReferenceSystem refSystem
= state
.getReferenceSystem(uuid
);
339 if (refSystem
== null){
340 refSystem
= (ReferenceSystem
)getTermService().find(uuid
);
341 if (refSystem
== null){
342 refSystem
= ReferenceSystem
.NewInstance(text
, label
, labelAbbrev
);
344 boolean isOrdered
= false;
345 voc
= getVocabulary(TermType
.ReferenceSystem
, uuidUserDefinedReferenceSystemVocabulary
, "User defined vocabulary for reference systems", "User Defined Reference System", null, null, isOrdered
, refSystem
);
347 voc
.addTerm(refSystem
);
348 refSystem
.setUuid(uuid
);
349 getTermService().save(refSystem
);
351 state
.putReferenceSystem(refSystem
);
359 protected Rank
getRank(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
,OrderedTermVocabulary
<Rank
> voc
, Rank lowerRank
, RankClass rankClass
){
361 uuid
= UUID
.randomUUID();
363 Rank rank
= state
.getRank(uuid
);
365 rank
= (Rank
)getTermService().find(uuid
);
367 rank
= Rank
.NewInstance(rankClass
, text
, label
, labelAbbrev
);
369 boolean isOrdered
= true;
370 voc
= (OrderedTermVocabulary
)getVocabulary(TermType
.Rank
, uuidUserDefinedRankVocabulary
, "User defined vocabulary for ranks", "User Defined Reference System", null, null, isOrdered
, rank
);
372 if (lowerRank
== null){
375 voc
.addTermAbove(rank
, lowerRank
);
378 getTermService().save(rank
);
387 * Returns a named area for a given uuid by first . If the named area does not
397 protected NamedArea
getNamedArea(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, NamedAreaType areaType
, NamedAreaLevel level
){
398 return getNamedArea(state
, uuid
, label
, text
, labelAbbrev
, areaType
, level
, null, null);
401 protected NamedArea
getNamedArea(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, NamedAreaType areaType
, NamedAreaLevel level
, TermVocabulary voc
, TermMatchMode matchMode
){
402 return getNamedArea(state
, uuid
, label
, text
, labelAbbrev
, areaType
, level
, voc
, matchMode
, null);
406 protected NamedArea
getNamedArea(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, NamedAreaType areaType
, NamedAreaLevel level
, TermVocabulary voc
, TermMatchMode matchMode
,
407 List
<TermVocabulary
<NamedArea
>> vocabularyPreference
){
408 Class
<NamedArea
> clazz
= NamedArea
.class;
410 uuid
= UUID
.randomUUID();
412 if (matchMode
== null){
413 matchMode
= TermMatchMode
.UUID_ONLY
;
415 NamedArea namedArea
= state
.getNamedArea(uuid
);
416 if (namedArea
== null){
417 DefinedTermBase
<?
> term
= getTermService().find(uuid
);
418 namedArea
= CdmBase
.deproxy(term
,NamedArea
.class);
420 if (vocabularyPreference
== null){
421 vocabularyPreference
= new ArrayList
<TermVocabulary
<NamedArea
>>();
423 if (vocabularyPreference
.isEmpty()){ //add TDWG vocabulary if preferences are empty
424 vocabularyPreference
.add(Country
.GERMANY().getVocabulary());
425 vocabularyPreference
.add(TdwgAreaProvider
.getAreaByTdwgAbbreviation("GER").getVocabulary());
429 //TODO matching still experimental
430 if (namedArea
== null && (matchMode
.equals(TermMatchMode
.UUID_LABEL
) || matchMode
.equals(TermMatchMode
.UUID_LABEL_ABBREVLABEL
))){
432 Pager
<NamedArea
> areaPager
= (Pager
)getTermService().findByTitle(clazz
, label
, null, null, null, null, null, null);
433 namedArea
= findBestMatchingArea(areaPager
, uuid
, label
, text
, labelAbbrev
, vocabularyPreference
);
435 if (namedArea
== null && (matchMode
.equals(TermMatchMode
.UUID_ABBREVLABEL
) || matchMode
.equals(TermMatchMode
.UUID_LABEL_ABBREVLABEL
))){
436 Pager
<NamedArea
> areaPager
= getTermService().findByRepresentationAbbreviation(labelAbbrev
, clazz
, null, null);
437 namedArea
= findBestMatchingArea(areaPager
, uuid
, label
, text
, labelAbbrev
, vocabularyPreference
);
440 if (namedArea
== null){
441 namedArea
= NamedArea
.NewInstance(text
, label
, labelAbbrev
);
443 boolean isOrdered
= true;
444 voc
= getVocabulary(TermType
.NamedArea
, uuidUserDefinedNamedAreaVocabulary
, "User defined vocabulary for named areas", "User Defined Named Areas", null, null, isOrdered
, namedArea
);
446 voc
.addTerm(namedArea
);
447 namedArea
.setType(areaType
);
448 namedArea
.setLevel(level
);
449 namedArea
.setUuid(uuid
);
450 getTermService().saveOrUpdate(namedArea
);
452 state
.putNamedArea(namedArea
);
458 private NamedArea
findBestMatchingArea(Pager
<NamedArea
> areaPager
, UUID uuid
, String label
, String text
, String abbrev
, List
<TermVocabulary
<NamedArea
>> vocabularyPreference
) {
459 // TODO preliminary implementation
460 List
<NamedArea
> list
= areaPager
.getRecords();
461 if (list
.size() == 0){
463 }else if (list
.size() == 1){
465 }else if (list
.size() > 1){
466 List
<NamedArea
> preferredList
= new ArrayList
<NamedArea
>();
467 for (TermVocabulary
<NamedArea
> voc
: vocabularyPreference
){
468 for (NamedArea area
: list
){
469 if (voc
.equals(area
.getVocabulary())){
470 preferredList
.add(area
);
473 if (preferredList
.size() > 0){
477 if (preferredList
.size() > 1 ){
478 preferredList
= getLowestLevelAreas(preferredList
);
479 }else if (preferredList
.size() == 0 ){
480 preferredList
= list
;
482 if (preferredList
.size() == 1 ){
483 return preferredList
.get(0);
484 }else if (preferredList
.size() > 1 ){
485 String message
= "There is more than 1 matching area for %s, %s, %s. As a preliminary implementation I take the first";
486 message
= String
.format(message
, label
, abbrev
, text
);
487 logger
.warn(message
);
495 private List
<NamedArea
> getLowestLevelAreas(List
<NamedArea
> preferredList
) {
496 List
<NamedArea
> result
= new ArrayList
<NamedArea
>();
497 for (NamedArea area
: preferredList
){
498 if (result
.isEmpty()){
501 int compare
= compareAreaLevel(area
, result
.get(0));
503 result
= new ArrayList
<NamedArea
>();
505 }else if (compare
== 0){
518 private int compareAreaLevel(NamedArea area1
, NamedArea area2
) {
519 NamedAreaLevel level1
= area1
.getLevel();
520 NamedAreaLevel level2
= area2
.getLevel();
522 return (level2
== null)?
0 : 1;
523 }else if (level2
== null){
526 return level1
.compareTo(level2
);
531 protected NamedAreaLevel
getNamedAreaLevel(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, TermVocabulary
<NamedAreaLevel
> voc
){
533 uuid
= UUID
.randomUUID();
535 NamedAreaLevel namedAreaLevel
= state
.getNamedAreaLevel(uuid
);
536 if (namedAreaLevel
== null){
537 //TODO propPath just for testing
538 List
<String
> propPath
= Arrays
.asList("vocabulary");
539 DefinedTermBase
<NamedAreaLevel
> term
= getTermService().load(uuid
, propPath
);
540 namedAreaLevel
= CdmBase
.deproxy(term
, NamedAreaLevel
.class);
541 if (namedAreaLevel
== null){
542 namedAreaLevel
= NamedAreaLevel
.NewInstance(text
, label
, labelAbbrev
);
544 boolean isOrdered
= true;
545 voc
= getVocabulary(TermType
.NamedAreaLevel
, uuidUserDefinedNamedAreaLevelVocabulary
, "User defined vocabulary for named area levels", "User Defined Named Area Levels", null, null, isOrdered
, namedAreaLevel
);
547 //FIXME only for debugging
548 Set
<NamedAreaLevel
> terms
= voc
.getTerms();
549 for (NamedAreaLevel level
: terms
){
550 TermVocabulary
<NamedAreaLevel
> levelVoc
= level
.getVocabulary();
551 if (levelVoc
== null){
552 logger
.error("ONLY FOR DEBUG: Level voc is null");
554 logger
.info("ONLY FOR DEBUG: Level voc is not null");
557 voc
.addTerm(namedAreaLevel
);
558 namedAreaLevel
.setUuid(uuid
);
559 getTermService().save(namedAreaLevel
);
561 state
.putNamedAreaLevel(namedAreaLevel
);
563 return namedAreaLevel
;
567 * Returns a {@link State} if it exists. <code>null</code> otherwise.
570 * @return {@link State}
572 protected State
getStateTerm(STATE state
, UUID uuid
){
573 return getStateTerm(state
, uuid
, null, null, null, null);
578 * Returns a {@link State} for a given uuid by first checking if the uuid has already been used in this import, if not
579 * checking if the state exists in the database, if not creating it anew (with vocabulary etc.).
580 * If label, text and labelAbbrev are all <code>null</code> no state is created.
589 protected State
getStateTerm(STATE importState
, UUID uuid
, String label
, String text
, String labelAbbrev
, OrderedTermVocabulary
<State
> voc
) {
593 State stateTerm
= importState
.getStateTerm(uuid
);
594 if (stateTerm
== null){
595 stateTerm
= CdmBase
.deproxy(getTermService().find(uuid
), State
.class);
596 if (stateTerm
== null && ! hasNoLabel(label
, text
, labelAbbrev
)){
597 stateTerm
= State
.NewInstance(text
, label
, labelAbbrev
);
598 stateTerm
.setUuid(uuid
);
600 boolean isOrdered
= true;
601 TermVocabulary
<State
> orderedVoc
= getVocabulary(TermType
.State
, uuidUserDefinedStateVocabulary
, "User defined vocabulary for states used by Categorical Data", "User Defined States", null, null, isOrdered
, stateTerm
);
602 voc
= CdmBase
.deproxy(orderedVoc
, OrderedTermVocabulary
.class);
604 voc
.addTerm(stateTerm
);
605 getTermService().save(stateTerm
);
607 logger
.warn("No label provided for new state with uuid " + uuid
);
609 importState
.putStateTerm(stateTerm
);
615 * Returns a feature if it exists, null otherwise.
616 * @see #getFeature(ImportStateBase, UUID, String, String, String, TermVocabulary)
621 protected Feature
getFeature(STATE state
, UUID uuid
){
622 return getFeature(state
, uuid
, null, null, null, null);
626 * Returns a feature for a given uuid by first checking if the uuid has already been used in this import, if not
627 * checking if the feature exists in the database, if not creating it anew (with vocabulary etc.).
628 * If label, text and labelAbbrev are all <code>null</code> no feature is created.
636 protected Feature
getFeature(STATE state
, UUID uuid
, String label
, String description
, String labelAbbrev
, TermVocabulary
<Feature
> voc
){
640 Feature feature
= state
.getFeature(uuid
);
641 if (feature
== null){
642 feature
= (Feature
)getTermService().find(uuid
);
643 if (feature
== null && ! hasNoLabel(label
, description
, labelAbbrev
)){
644 feature
= Feature
.NewInstance(description
, label
, labelAbbrev
);
645 feature
.setUuid(uuid
);
646 feature
.setSupportsTextData(true);
647 // UUID uuidFeatureVoc = UUID.fromString("b187d555-f06f-4d65-9e53-da7c93f8eaa8");
649 boolean isOrdered
= false;
650 voc
= getVocabulary(TermType
.Feature
, uuidUserDefinedFeatureVocabulary
, "User defined vocabulary for features", "User Defined Features", null, null, isOrdered
, feature
);
652 voc
.addTerm(feature
);
653 getTermService().save(feature
);
655 state
.putFeature(feature
);
660 protected DefinedTerm
getKindOfUnit(STATE state
, UUID uuid
, String label
, String description
, String labelAbbrev
, TermVocabulary
<DefinedTerm
> voc
){
662 uuid
= UUID
.randomUUID();
664 DefinedTerm unit
= state
.getKindOfUnit(uuid
);
666 unit
= (DefinedTerm
)getTermService().find(uuid
);
667 if (unit
== null && ! hasNoLabel(label
, description
, labelAbbrev
)){
668 unit
= DefinedTerm
.NewKindOfUnitInstance(description
, label
, labelAbbrev
);
671 boolean isOrdered
= false;
672 voc
= getVocabulary(TermType
.KindOfUnit
, uuidUserDefinedKindOfUnitVocabulary
, "User defined vocabulary for kind-of-units", "User Defined Measurement kind-of-units", null, null, isOrdered
, unit
);
675 getTermService().save(unit
);
677 state
.putKindOfUnit(unit
);
683 * Returns a {@link MeasurementUnit} for a given uuid by first checking if the uuid has already been used in this import, if not
684 * checking if the {@link MeasurementUnit} exists in the database, if not creating it anew (with vocabulary etc.).
685 * If label, text and labelAbbrev are all <code>null</code> no {@link MeasurementUnit} is created.
693 protected MeasurementUnit
getMeasurementUnit(STATE state
, UUID uuid
, String label
, String description
, String labelAbbrev
, TermVocabulary
<MeasurementUnit
> voc
){
697 MeasurementUnit unit
= state
.getMeasurementUnit(uuid
);
699 unit
= (MeasurementUnit
)getTermService().find(uuid
);
700 if (unit
== null && ! hasNoLabel(label
, description
, labelAbbrev
)){
701 unit
= MeasurementUnit
.NewInstance(description
, label
, labelAbbrev
);
704 boolean isOrdered
= false;
705 voc
= getVocabulary(TermType
.MeasurementUnit
, uuidUserDefinedMeasurementUnitVocabulary
, "User defined vocabulary for measurement units", "User Defined Measurement Units", null, null, isOrdered
, unit
);
708 getTermService().save(unit
);
710 state
.putMeasurementUnit(unit
);
716 * Returns a {@link StatisticalMeasure} for a given uuid by first checking if the uuid has already been used in this import, if not
717 * checking if the {@link StatisticalMeasure} exists in the database, if not creating it anew (with vocabulary etc.).
718 * If label, text and labelAbbrev are all <code>null</code> no {@link StatisticalMeasure} is created.
726 protected StatisticalMeasure
getStatisticalMeasure(STATE state
, UUID uuid
, String label
, String description
, String labelAbbrev
, TermVocabulary
<StatisticalMeasure
> voc
){
730 StatisticalMeasure statisticalMeasure
= state
.getStatisticalMeasure(uuid
);
731 if (statisticalMeasure
== null){
732 statisticalMeasure
= (StatisticalMeasure
)getTermService().find(uuid
);
733 if (statisticalMeasure
== null && ! hasNoLabel(label
, description
, labelAbbrev
)){
734 statisticalMeasure
= StatisticalMeasure
.NewInstance(description
, label
, labelAbbrev
);
735 statisticalMeasure
.setUuid(uuid
);
737 boolean isOrdered
= false;
738 voc
= getVocabulary(TermType
.StatisticalMeasure
, uuidUserDefinedStatisticalMeasureVocabulary
, "User defined vocabulary for statistical measures", "User Defined Statistical Measures", null, null, isOrdered
, statisticalMeasure
);
740 voc
.addTerm(statisticalMeasure
);
741 getTermService().save(statisticalMeasure
);
743 state
.putStatisticalMeasure(statisticalMeasure
);
745 return statisticalMeasure
;
749 * Returns a {@link Modifier} for a given uuid by first checking if the uuid has already been used in this import, if not
750 * checking if the {@link Modifier} exists in the database, if not creating it anew (with vocabulary etc.).
751 * If label, text and labelAbbrev are all <code>null</code> no {@link Modifier} is created.
759 protected DefinedTerm
getModifier(STATE state
, UUID uuid
, String label
, String description
, String labelAbbrev
, TermVocabulary
<DefinedTerm
> voc
){
763 DefinedTerm modifier
= state
.getModifier(uuid
);
764 if (modifier
== null){
765 modifier
= (DefinedTerm
)getTermService().find(uuid
);
766 if (modifier
== null && ! hasNoLabel(label
, description
, labelAbbrev
)){
767 modifier
= DefinedTerm
.NewModifierInstance(description
, label
, labelAbbrev
);
768 modifier
.setUuid(uuid
);
770 boolean isOrdered
= false;
771 voc
= getVocabulary(TermType
.Modifier
, uuidUserDefinedModifierVocabulary
, "User defined vocabulary for modifier", "User Defined Modifier", null, null, isOrdered
, modifier
);
773 voc
.addTerm(modifier
);
774 getTermService().save(modifier
);
776 state
.putModifier(modifier
);
782 * Returns a taxon relationship type for a given uuid by first checking if the uuid has already been used in this import, if not
783 * checking if the taxon relationship type exists in the database, if not creating it anew (with vocabulary etc.).
784 * If label, text and labelAbbrev are all <code>null</code> no taxon relationship type is created.
792 protected TaxonRelationshipType
getTaxonRelationshipType(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, TermVocabulary
<TaxonRelationshipType
> voc
){
796 TaxonRelationshipType relType
= state
.getTaxonRelationshipType(uuid
);
797 if (relType
== null){
798 relType
= (TaxonRelationshipType
)getTermService().find(uuid
);
799 if (relType
== null && ! hasNoLabel(label
, text
, labelAbbrev
)){
800 relType
= TaxonRelationshipType
.NewInstance(text
, label
, labelAbbrev
, false, false);
801 relType
.setUuid(uuid
);
803 boolean isOrdered
= true;
804 voc
= getVocabulary(TermType
.TaxonRelationshipType
, uuidUserDefinedTaxonRelationshipTypeVocabulary
, "User defined vocabulary for taxon relationship types", "User Defined Taxon Relationship Types", null, null, isOrdered
, relType
);
806 voc
.addTerm(relType
);
807 getTermService().save(relType
);
809 state
.putTaxonRelationshipType(relType
);
814 private boolean hasNoLabel(String label
, String text
, String labelAbbrev
) {
815 return label
== null && text
== null && labelAbbrev
== null;
818 protected PresenceAbsenceTerm
getPresenceTerm(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, boolean isAbsenceTerm
){
819 return getPresenceTerm(state
, uuid
, label
, text
, labelAbbrev
, isAbsenceTerm
, null);
824 * Returns a presence term for a given uuid by first ...
832 protected PresenceAbsenceTerm
getPresenceTerm(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, boolean isAbsenceTerm
, TermVocabulary
<PresenceAbsenceTerm
> voc
){
836 PresenceAbsenceTerm presenceTerm
= state
.getPresenceAbsenceTerm(uuid
);
837 if (presenceTerm
== null){
838 presenceTerm
= (PresenceAbsenceTerm
)getTermService().find(uuid
);
839 if (presenceTerm
== null){
840 presenceTerm
= PresenceAbsenceTerm
.NewPresenceInstance(text
, label
, labelAbbrev
);
841 presenceTerm
.setUuid(uuid
);
842 presenceTerm
.setAbsenceTerm(isAbsenceTerm
);
843 //set vocabulary ; FIXME use another user-defined vocabulary
845 boolean isOrdered
= true;
846 voc
= getVocabulary(TermType
.PresenceAbsenceTerm
, uuidUserDefinedPresenceAbsenceVocabulary
, "User defined vocabulary for distribution status", "User Defined Distribution Status", null, null, isOrdered
, presenceTerm
);
848 voc
.addTerm(presenceTerm
);
849 getTermService().save(presenceTerm
);
851 state
.putPresenceAbsenceTerm(presenceTerm
);
857 * Returns a language for a given uuid by first ...
865 protected Language
getLanguage(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
){
866 return getLanguage(state
, uuid
, label
, text
, labelAbbrev
, null);
869 protected Language
getLanguage(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, TermVocabulary voc
){
873 Language language
= state
.getLanguage(uuid
);
874 if (language
== null){
875 language
= (Language
)getTermService().find(uuid
);
876 if (language
== null){
877 language
= Language
.NewInstance(text
, label
, labelAbbrev
);
879 language
.setUuid(uuid
);
881 UUID uuidLanguageVoc
= UUID
.fromString("463a96f1-20ba-4a4c-9133-854c1682bd9b");
882 boolean isOrdered
= false;
883 voc
= getVocabulary(TermType
.Language
, uuidLanguageVoc
, "User defined languages", "User defined languages", "User defined languages", null, isOrdered
, language
);
885 //set vocabulary ; FIXME use another user-defined vocabulary
887 voc
.addTerm(language
);
888 getTermService().save(language
);
890 state
.putLanguage(language
);
901 protected <T
extends DefinedTermBase
> TermVocabulary
<T
> getVocabulary(TermType termType
, UUID uuid
, String description
, String label
, String abbrev
, URI termSourceUri
, boolean isOrdered
, T type
) {
902 List
<String
> propPath
= Arrays
.asList(new String
[]{"terms"});
903 TermVocabulary
<T
> voc
= getVocabularyService().load(uuid
, propPath
);
906 voc
= OrderedTermVocabulary
.NewInstance(termType
, description
, label
, abbrev
, termSourceUri
);
908 voc
= TermVocabulary
.NewInstance(termType
, description
, label
, abbrev
, termSourceUri
);
911 getVocabularyService().save(voc
);
917 * Adds an orginal source to a sourceable objects (implemented for Identifiable entity and description element.
918 * If cdmBase is not sourceable nothing happens.
919 * TODO Move to DbImportBase once this exists.
920 * TODO also implemented in DbImportObjectCreationMapper (reduce redundance)
923 * @param dbIdAttribute
926 * @throws SQLException
928 public void addOriginalSource(CdmBase cdmBase
, Object idAttributeValue
, String namespace
, Reference citation
) {
929 if (cdmBase
instanceof ISourceable
){
930 IOriginalSource source
;
931 ISourceable sourceable
= (ISourceable
<?
>)cdmBase
;
932 Object id
= idAttributeValue
;
933 String strId
= String
.valueOf(id
);
934 String microCitation
= null;
935 OriginalSourceType type
= OriginalSourceType
.Import
;
936 if (cdmBase
instanceof IdentifiableEntity
){
937 source
= IdentifiableSource
.NewInstance(type
, strId
, namespace
, citation
, microCitation
);
938 }else if (cdmBase
instanceof DescriptionElementBase
){
939 source
= DescriptionElementSource
.NewInstance(type
, strId
, namespace
, citation
, microCitation
);
941 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.");
944 sourceable
.addSource(source
);
945 }else if (cdmBase
!= null){
946 logger
.warn("Sourced object does not implement ISourceable: " + cdmBase
.getClass() + "," + cdmBase
.getUuid());
948 logger
.warn("Sourced object is null");
953 * @see #addOriginalSource(CdmBase, Object, String, Reference)
956 * @param dbIdAttribute
959 * @throws SQLException
961 public void addOriginalSource(ResultSet rs
, CdmBase cdmBase
, String dbIdAttribute
, String namespace
, Reference citation
) throws SQLException
{
962 Object id
= rs
.getObject(dbIdAttribute
);
963 addOriginalSource(cdmBase
, id
, namespace
, citation
);
968 * If the child taxon is missing genus or species epithet information and the rank is below <i>genus</i>
969 * or <i>species</i> respectively the according epithets are taken from the parent taxon.
970 * If the name is an autonym and has no combination author/basionym author the authors are taken from
975 protected void fillMissingEpithetsForTaxa(Taxon parentTaxon
, Taxon childTaxon
) {
976 if (parentTaxon
== null){
977 logger
.warn("Parent taxon is null. Missing name parts can not be taken from parent");
980 INonViralName parentName
= parentTaxon
.getName();
981 INonViralName childName
= childTaxon
.getName();
982 fillMissingEpithets(parentName
, childName
);
986 * If the child name is missing genus or species epithet information and the rank is below <i>genus</i>
987 * or <i>species</i> respectively the according epithets are taken from the parent name.
988 * If the name is an autonym and has no combination author/basionym author the authors are taken from
993 protected void fillMissingEpithets(INonViralName parentName
, INonViralName childName
) {
994 if (StringUtils
.isBlank(childName
.getGenusOrUninomial()) && childName
.getRank().isLower(Rank
.GENUS()) ){
995 childName
.setGenusOrUninomial(parentName
.getGenusOrUninomial());
998 if (StringUtils
.isBlank(childName
.getSpecificEpithet()) && childName
.getRank().isLower(Rank
.SPECIES()) ){
999 childName
.setSpecificEpithet(parentName
.getSpecificEpithet());
1001 if (childName
.isAutonym() && childName
.getCombinationAuthorship() == null && childName
.getBasionymAuthorship() == null ){
1002 childName
.setCombinationAuthorship(parentName
.getCombinationAuthorship());
1003 childName
.setBasionymAuthorship(parentName
.getBasionymAuthorship());
1008 * Returns the taxon description for a taxon. If there are multiple taxon descriptions
1009 * an arbitrary one is chosen.
1010 * If no taxon description exists, a new one is created if <code>createNewIfNotExists</code>
1011 * is <code>true</code>.
1012 * @param createNewIfNotExists
1013 * @param isImageGallery if true only taxon description being image galleries are considered.
1014 * If false only taxon description being no image galleries are considered.
1017 public TaxonNameDescription
getTaxonNameDescription(TaxonNameBase name
, boolean isImageGallery
, boolean createNewIfNotExists
) {
1018 Reference ref
= null;
1019 return getTaxonNameDescription(name
, ref
, isImageGallery
, createNewIfNotExists
);
1023 * Like {@link #getTaxonDescription(Taxon, boolean, boolean)}
1024 * Only matches a description if the given reference is a source of the description.<BR>
1025 * If a new description is created the given reference will be added as a source.
1027 * @see #getTaxonDescription(Taxon, boolean, boolean)
1029 public TaxonNameDescription
getTaxonNameDescription(TaxonNameBase
<?
,?
> name
, Reference ref
, boolean isImageGallery
, boolean createNewIfNotExists
) {
1030 TaxonNameDescription result
= null;
1031 Set
<TaxonNameDescription
> descriptions
= name
.getDescriptions();
1032 for (TaxonNameDescription description
: descriptions
){
1033 if (description
.isImageGallery() == isImageGallery
){
1034 if (hasCorrespondingSource(ref
, description
)){
1035 result
= description
;
1040 if (result
== null && createNewIfNotExists
){
1041 result
= TaxonNameDescription
.NewInstance(name
);
1042 result
.setImageGallery(isImageGallery
);
1044 result
.addImportSource(null, null, ref
, null);
1051 * Returns the taxon description for a taxon. If there are multiple taxon descriptions
1052 * an arbitrary one is chosen.
1053 * If no taxon description exists, a new one is created if <code>createNewIfNotExists</code>
1054 * is <code>true</code>.
1055 * @param createNewIfNotExists
1056 * @param isImageGallery if true only taxon description being image galleries are considered.
1057 * If false only taxon description being no image galleries are considered.
1060 public TaxonDescription
getTaxonDescription(Taxon taxon
, boolean isImageGallery
, boolean createNewIfNotExists
) {
1061 Reference ref
= null;
1062 return getTaxonDescription(taxon
, ref
, isImageGallery
, createNewIfNotExists
);
1066 * Like {@link #getTaxonDescription(Taxon, boolean, boolean)}
1067 * Only matches a description if the given reference is a source of the description.<BR>
1068 * If a new description is created the given reference will be added as a source.
1070 * @see #getTaxonDescription(Taxon, boolean, boolean)
1072 public TaxonDescription
getTaxonDescription(Taxon taxon
, Reference ref
, boolean isImageGallery
, boolean createNewIfNotExists
) {
1073 TaxonDescription result
= null;
1074 Set
<TaxonDescription
> descriptions
= taxon
.getDescriptions();
1075 for (TaxonDescription description
: descriptions
){
1076 if (description
.isImageGallery() == isImageGallery
){
1077 if (hasCorrespondingSource(ref
, description
)){
1078 result
= description
;
1083 if (result
== null && createNewIfNotExists
){
1084 result
= TaxonDescription
.NewInstance(taxon
);
1085 result
.setImageGallery(isImageGallery
);
1087 result
.addImportSource(null, null, ref
, null);
1095 * Returns the {@link SpecimenDescription specimen description} for a {@link SpecimenOrObservationBase specimen or observation}.
1096 * If there are multiple specimen descriptions an arbitrary one is chosen.
1097 * If no specimen description exists, a new one is created if <code>createNewIfNotExists</code> is <code>true</code>.
1098 * @param createNewIfNotExists
1099 * @param isImageGallery if true only specimen description being image galleries are considered.
1100 * If false only specimen description being no image galleries are considered.
1103 public SpecimenDescription
getSpecimenDescription(SpecimenOrObservationBase specimen
, boolean isImageGallery
, boolean createNewIfNotExists
) {
1104 Reference ref
= null;
1105 return getSpecimenDescription(specimen
, ref
, isImageGallery
, createNewIfNotExists
);
1109 * Like {@link #getSpecimenDescription(SpecimenOrObservationBase, boolean, boolean)}
1110 * Only matches a description if the given reference is a source of the description.<BR>
1111 * If a new description is created the given reference will be added as a source.
1113 * @see #getTaxonDescription(Taxon, boolean, boolean)
1115 public SpecimenDescription
getSpecimenDescription(SpecimenOrObservationBase specimen
, Reference ref
, boolean isImageGallery
, boolean createNewIfNotExists
) {
1116 SpecimenDescription result
= null;
1117 Set
<SpecimenDescription
> descriptions
= specimen
.getDescriptions();
1118 for (SpecimenDescription description
: descriptions
){
1119 if (description
.isImageGallery() == isImageGallery
){
1120 if (hasCorrespondingSource(ref
, description
)){
1121 result
= description
;
1126 if (result
== null && createNewIfNotExists
){
1127 result
= SpecimenDescription
.NewInstance(specimen
);
1128 result
.setImageGallery(isImageGallery
);
1130 result
.addImportSource(null, null, ref
, null);
1138 * Returns the textdata that holds general information about a feature for a taxon description.
1139 * This is mainly necessary for descriptions that have more than one description element for
1140 * a given feature such as 'distribution', 'description' or 'common name'. It may also hold
1141 * for hierarchical features where no description element exists for a higher hierarchy level.
1142 * Example: the description feature has subfeatures. But some information like authorship, figures,
1143 * sources need to be added to the description itself.
1144 * Currently a feature placeholder is marked by a marker of type 'feature placeholder'. Maybe in future
1145 * there will be a boolean marker in the TextData class itself.
1150 * @param createIfNotExists
1153 protected TextData
getFeaturePlaceholder(STATE state
, DescriptionBase
<?
> description
, Feature feature
, boolean createIfNotExists
) {
1154 UUID featurePlaceholderUuid
= MarkupTransformer
.uuidFeaturePlaceholder
;
1155 for (DescriptionElementBase element
: description
.getElements()){
1156 if (element
.isInstanceOf(TextData
.class)){
1157 TextData textData
= CdmBase
.deproxy(element
, TextData
.class);
1158 if (textData
.getFeature() == null || ! textData
.getFeature().equals(feature
)){
1161 for (Marker marker
: textData
.getMarkers()){
1162 MarkerType markerType
= marker
.getMarkerType();
1163 if (markerType
!= null &&
1164 markerType
.getUuid().equals(featurePlaceholderUuid
) &&
1165 marker
.getValue() == true){
1171 if (createIfNotExists
){
1172 TextData newPlaceholder
= TextData
.NewInstance(feature
);
1173 MarkerType placeholderMarkerType
= getMarkerType(state
, featurePlaceholderUuid
, "Feature Placeholder", "Feature Placeholder", null);
1174 Marker marker
= Marker
.NewInstance(placeholderMarkerType
, true);
1175 newPlaceholder
.addMarker(marker
);
1176 description
.addElement(newPlaceholder
);
1177 return newPlaceholder
;
1186 * Returns true, if this description has a source with a citation equal to the given reference.
1187 * Returns true if the given reference is null.
1189 * @param description
1191 private boolean hasCorrespondingSource(Reference ref
, DescriptionBase
<?
> description
) {
1193 for (IdentifiableSource source
: description
.getSources()){
1194 if (ref
.equals(source
.getCitation())){
1206 * Returns the accepted taxon of a {@link TaxonBase taxon base}. <BR>
1207 * If taxonBase is of type taxon the same object is returned. If taxonBase is of type
1208 * synonym the accepted taxon is returned if one exists. If no accepted taxon exists
1209 * <code>null</code> is returned. If multiple accepted taxa exist the one taxon with the
1210 * same secundum reference is returned. If no such single taxon exists an
1211 * {@link IllegalStateException illegal state exception} is thrown.
1215 protected Taxon
getAcceptedTaxon(TaxonBase
<?
> taxonBase
) {
1216 if (taxonBase
== null){
1218 }else if(taxonBase
.isInstanceOf(Taxon
.class)){
1219 return CdmBase
.deproxy(taxonBase
, Taxon
.class);
1220 }else if(taxonBase
.isInstanceOf(Synonym
.class)){
1221 Synonym synonym
= CdmBase
.deproxy(taxonBase
, Synonym
.class);
1222 Taxon acceptedTaxon
= synonym
.getAcceptedTaxon();
1223 return acceptedTaxon
;
1225 throw new IllegalStateException("Unknown TaxonBase subclass: " + taxonBase
.getClass().getName());
1234 * @param readDataFromUrl
1235 * @see #READ_MEDIA_DATA
1237 * @throws MalformedURLException
1239 protected Media
getImageMedia(String uriString
, boolean readMediaData
) throws MalformedURLException
{
1240 if( uriString
== null){
1243 ImageInfo imageInfo
= null;
1245 uriString
= uriString
.replace(" ", "%20"); //replace whitespace
1247 uri
= new URI(uriString
);
1250 logger
.info("Read media data from: " + uri
);
1251 imageInfo
= ImageInfo
.NewInstance(uri
, 0);
1253 } catch (Exception e
) {
1254 String message
= "An error occurred when trying to read image meta data for " + uri
.toString() + ": " + e
.getMessage();
1255 logger
.warn(message
);
1256 fireWarningEvent(message
, "unknown location", 2, 0);
1258 ImageFile imageFile
= ImageFile
.NewInstance(uri
, null, imageInfo
);
1259 MediaRepresentation representation
= MediaRepresentation
.NewInstance();
1260 if(imageInfo
!= null){
1261 representation
.setMimeType(imageInfo
.getMimeType());
1262 representation
.setSuffix(imageInfo
.getSuffix());
1264 representation
.addRepresentationPart(imageFile
);
1265 Media media
= Media
.NewInstance();
1266 media
.addRepresentation(representation
);
1268 } catch (URISyntaxException e1
) {
1269 String message
= "An URISyntaxException occurred when trying to create uri from multimedia objcet string: " + uriString
;
1270 logger
.warn(message
);
1271 fireWarningEvent(message
, "unknown location", 4, 0);
1279 * Retrieves an Integer value from a result set. If the value is NULL null is returned.
1280 * ResultSet.getInt() returns 0 therefore we need a special handling for this case.
1284 * @throws SQLException
1286 protected Integer
nullSafeInt(ResultSet rs
, String columnName
) throws SQLException
{
1287 Object intObject
= rs
.getObject(columnName
);
1288 if (intObject
== null){
1291 return Integer
.valueOf(intObject
.toString());
1295 protected Boolean
nullSafeBoolean(ResultSet rs
, String columnName
) throws SQLException
{
1296 Object bitObject
= rs
.getObject(columnName
);
1297 if (bitObject
== null){
1300 return Boolean
.valueOf(bitObject
.toString());
1304 protected Double
nullSafeDouble(ResultSet rs
, String columnName
) throws SQLException
{
1305 Object doubleObject
= rs
.getObject(columnName
);
1306 if (doubleObject
== null){
1309 return Double
.valueOf(doubleObject
.toString());
1313 protected Float
nullSafeFloat(ResultSet rs
, String columnName
) throws SQLException
{
1314 Object doubleObject
= rs
.getObject(columnName
);
1315 if (doubleObject
== null){
1318 return Float
.valueOf(doubleObject
.toString());
1324 * Returns <code>null</code> for all blank strings. Identity function otherwise.
1328 protected String
NB(String str
) {
1329 if (StringUtils
.isBlank(str
)){
1337 public byte[] getByteArray() {
1338 // TODO Auto-generated method stub
1342 public static TeamOrPersonBase
<?
> parseAuthorString(String authorName
){
1343 TeamOrPersonBase
<?
> author
= null;
1344 String
[] teamMembers
= authorName
.split(authorSeparator
);
1346 String
[] lastMembers
;
1348 if (teamMembers
.length
>1){
1349 lastMember
= teamMembers
[teamMembers
.length
-1];
1350 lastMembers
= lastMember
.split(lastAuthorSeparator
);
1351 teamMembers
[teamMembers
.length
-1] = "";
1352 author
= Team
.NewInstance();
1353 for(String member
:teamMembers
){
1354 if (!member
.equals("")){
1355 teamMember
= Person
.NewInstance();
1356 teamMember
.setTitleCache(member
, true);
1357 ((Team
)author
).addTeamMember(teamMember
);
1360 if (lastMembers
!= null){
1361 for(String member
:lastMembers
){
1362 teamMember
= Person
.NewInstance();
1363 teamMember
.setTitleCache(member
, true);
1364 ((Team
)author
).addTeamMember(teamMember
);
1369 teamMembers
= authorName
.split(lastAuthorSeparator
);
1370 if (teamMembers
.length
>1){
1371 author
= Team
.NewInstance();
1372 for(String member
:teamMembers
){
1373 teamMember
= Person
.NewInstance();
1374 teamMember
.setTitleCache(member
, true);
1375 ((Team
)author
).addTeamMember(teamMember
);
1379 author
= Person
.NewInstance();
1380 author
.setTitleCache(authorName
, true);
1383 author
.getTitleCache();