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
.HashSet
;
20 import java
.util
.List
;
22 import java
.util
.UUID
;
24 import org
.apache
.commons
.lang
.StringUtils
;
25 import org
.apache
.log4j
.Logger
;
27 import eu
.etaxonomy
.cdm
.api
.service
.pager
.Pager
;
28 import eu
.etaxonomy
.cdm
.common
.media
.ImageInfo
;
29 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
30 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.IInputTransformer
;
31 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.UndefinedTransformerMethodException
;
32 import eu
.etaxonomy
.cdm
.io
.markup
.MarkupTransformer
;
33 import eu
.etaxonomy
.cdm
.model
.common
.AnnotationType
;
34 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
35 import eu
.etaxonomy
.cdm
.model
.common
.DefinedTerm
;
36 import eu
.etaxonomy
.cdm
.model
.common
.DefinedTermBase
;
37 import eu
.etaxonomy
.cdm
.model
.common
.ExtensionType
;
38 import eu
.etaxonomy
.cdm
.model
.common
.IOriginalSource
;
39 import eu
.etaxonomy
.cdm
.model
.common
.ISourceable
;
40 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
41 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableSource
;
42 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
43 import eu
.etaxonomy
.cdm
.model
.common
.Marker
;
44 import eu
.etaxonomy
.cdm
.model
.common
.MarkerType
;
45 import eu
.etaxonomy
.cdm
.model
.common
.OrderedTermVocabulary
;
46 import eu
.etaxonomy
.cdm
.model
.common
.OriginalSourceType
;
47 import eu
.etaxonomy
.cdm
.model
.common
.TermType
;
48 import eu
.etaxonomy
.cdm
.model
.common
.TermVocabulary
;
49 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionBase
;
50 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
51 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementSource
;
52 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
53 import eu
.etaxonomy
.cdm
.model
.description
.MeasurementUnit
;
54 import eu
.etaxonomy
.cdm
.model
.description
.PresenceTerm
;
55 import eu
.etaxonomy
.cdm
.model
.description
.SpecimenDescription
;
56 import eu
.etaxonomy
.cdm
.model
.description
.State
;
57 import eu
.etaxonomy
.cdm
.model
.description
.StatisticalMeasure
;
58 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
59 import eu
.etaxonomy
.cdm
.model
.description
.TaxonNameDescription
;
60 import eu
.etaxonomy
.cdm
.model
.description
.TextData
;
61 import eu
.etaxonomy
.cdm
.model
.location
.Country
;
62 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
63 import eu
.etaxonomy
.cdm
.model
.location
.NamedAreaLevel
;
64 import eu
.etaxonomy
.cdm
.model
.location
.NamedAreaType
;
65 import eu
.etaxonomy
.cdm
.model
.location
.ReferenceSystem
;
66 import eu
.etaxonomy
.cdm
.model
.media
.ImageFile
;
67 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
68 import eu
.etaxonomy
.cdm
.model
.media
.MediaRepresentation
;
69 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
70 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
71 import eu
.etaxonomy
.cdm
.model
.name
.RankClass
;
72 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
73 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
74 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
75 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
76 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
77 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
78 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
79 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 Logger logger
= Logger
.getLogger(CdmImportBase
.class);
89 protected static final boolean CREATE
= true;
90 protected static final boolean IMAGE_GALLERY
= true;
91 protected static final boolean READ_MEDIA_DATA
= true;
93 public static final UUID uuidUserDefinedNamedAreaLevelVocabulary
= UUID
.fromString("255144da-8d95-457e-a327-9752a8f85e5a");
94 public static final UUID uuidUserDefinedNamedAreaVocabulary
= UUID
.fromString("b2238399-a3af-4f6d-b7eb-ff5d0899bf1b");
95 public static final UUID uuidUserDefinedExtensionTypeVocabulary
= UUID
.fromString("e28c1394-1be8-4847-8b81-ab44eb6d5bc8");
96 public static final UUID uuidUserDefinedReferenceSystemVocabulary
= UUID
.fromString("467591a3-10b4-4bf1-9239-f06ece33e90a");
97 public static final UUID uuidUserDefinedFeatureVocabulary
= UUID
.fromString("fe5fccb3-a2f2-4b97-b199-6e2743cf1627");
98 public static final UUID uuidUserDefinedMeasurementUnitVocabulary
= UUID
.fromString("d5e72bb7-f312-4080-bb86-c695d04a6e66");
99 public static final UUID uuidUserDefinedStatisticalMeasureVocabulary
= UUID
.fromString("62a89836-c730-4b4f-a904-3d859dbfc400");
100 public static final UUID uuidUserDefinedStateVocabulary
= UUID
.fromString("f7cddb49-8392-4db1-8640-65b48a0e6d13");
101 public static final UUID uuidUserDefinedTaxonRelationshipTypeVocabulary
= UUID
.fromString("31a324dc-408d-4877-891f-098db21744c6");
102 public static final UUID uuidUserDefinedAnnotationTypeVocabulary
= UUID
.fromString("cd9ecdd2-9cae-4890-9032-ad83293ae883");
103 public static final UUID uuidUserDefinedMarkerTypeVocabulary
= UUID
.fromString("5f02a261-fd7d-4fce-bbe4-21472de8cd51");
104 public static final UUID uuidUserDefinedRankVocabulary
= UUID
.fromString("4dc57931-38e2-46c3-974d-413b087646ba");
106 public static final UUID uuidUserDefinedModifierVocabulary
= UUID
.fromString("2a8b3838-3a95-49ea-9ab2-3049614b5884");
107 public static final UUID uuidUserDefinedKindOfUnitVocabulary
= UUID
.fromString("e7c5deb2-f485-4a66-9104-0c5398efd481");
111 private static final String UuidOnly
= "UUIDOnly";
112 private static final String UuidLabel
= "UUID or label";
113 private static final String UuidLabelAbbrev
= "UUID, label or abbreviation";
114 private static final String UuidAbbrev
= "UUID or abbreviation";
116 public enum TermMatchMode
{
117 UUID_ONLY(0, UuidOnly
)
118 ,UUID_LABEL(1, UuidLabel
)
119 ,UUID_LABEL_ABBREVLABEL(2, UuidLabelAbbrev
)
120 ,UUID_ABBREVLABEL(3, UuidAbbrev
)
125 private String representation
;
126 private TermMatchMode(int id
, String representation
){
128 this.representation
= representation
;
133 public String
getRepresentation() {
134 return representation
;
136 public TermMatchMode
valueOf(int id
){
138 case 0: return UUID_ONLY
;
139 case 1: return UUID_LABEL
;
140 case 2: return UUID_LABEL_ABBREVLABEL
;
141 case 3: return UUID_ABBREVLABEL
;
142 default: return UUID_ONLY
;
149 protected Classification
makeTree(STATE state
, Reference
<?
> reference
){
150 String treeName
= "Classification (Import)";
151 if (reference
!= null && StringUtils
.isNotBlank(reference
.getTitleCache())){
152 treeName
= reference
.getTitleCache();
154 Classification tree
= Classification
.NewInstance(treeName
);
155 tree
.setReference(reference
);
158 // use defined uuid for first tree
159 CONFIG config
= (CONFIG
)state
.getConfig();
160 if (state
.countTrees() < 1 ){
161 tree
.setUuid(config
.getClassificationUuid());
163 getClassificationService().save(tree
);
164 state
.putTree(reference
, tree
);
170 * Alternative memory saving method variant of
171 * {@link #makeTree(STATE state, Reference ref)} which stores only the
172 * UUID instead of the full tree in the <code>ImportStateBase</code> by
173 * using <code>state.putTreeUuid(ref, tree);</code>
179 protected Classification
makeTreeMemSave(STATE state
, Reference ref
){
180 String treeName
= "Classification (Import)";
181 if (ref
!= null && StringUtils
.isNotBlank(ref
.getTitleCache())){
182 treeName
= ref
.getTitleCache();
184 Classification tree
= Classification
.NewInstance(treeName
);
185 tree
.setReference(ref
);
188 // use defined uuid for first tree
189 CONFIG config
= (CONFIG
)state
.getConfig();
190 if (state
.countTrees() < 1 ){
191 tree
.setUuid(config
.getClassificationUuid());
193 getClassificationService().save(tree
);
194 state
.putTreeUuid(ref
, tree
);
199 protected ExtensionType
getExtensionType(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
){
200 return getExtensionType(state
, uuid
, label
, text
, labelAbbrev
, null);
202 protected ExtensionType
getExtensionType(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, TermVocabulary
<ExtensionType
> voc
){
204 uuid
= UUID
.randomUUID();
206 ExtensionType extensionType
= state
.getExtensionType(uuid
);
207 if (extensionType
== null){
208 extensionType
= (ExtensionType
)getTermService().find(uuid
);
209 if (extensionType
== null){
210 extensionType
= ExtensionType
.NewInstance(text
, label
, labelAbbrev
);
211 extensionType
.setUuid(uuid
);
213 boolean isOrdered
= false;
214 voc
= getVocabulary(TermType
.ExtensionType
, uuidUserDefinedExtensionTypeVocabulary
, "User defined vocabulary for extension types", "User Defined Extension Types", null, null, isOrdered
, extensionType
);
216 voc
.addTerm(extensionType
);
217 getTermService().saveOrUpdate(extensionType
);
219 state
.putExtensionType(extensionType
);
221 return extensionType
;
225 protected MarkerType
getMarkerType(STATE state
, String keyString
) {
226 IInputTransformer transformer
= state
.getTransformer();
227 MarkerType markerType
= null;
229 markerType
= transformer
.getMarkerTypeByKey(keyString
);
230 } catch (UndefinedTransformerMethodException e
) {
231 logger
.info("getMarkerTypeByKey not yet implemented for this import");
233 if (markerType
== null ){
236 uuid
= transformer
.getMarkerTypeUuid(keyString
);
237 return getMarkerType(state
, uuid
, keyString
, keyString
, keyString
);
238 } catch (UndefinedTransformerMethodException e
) {
239 logger
.warn("getMarkerTypeUuid not yet implemented for this import");
245 protected MarkerType
getMarkerType(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
){
246 return getMarkerType(state
, uuid
, label
, text
, labelAbbrev
, null);
250 protected MarkerType
getMarkerType(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, TermVocabulary
<MarkerType
> voc
){
252 uuid
= UUID
.randomUUID();
254 MarkerType markerType
= state
.getMarkerType(uuid
);
255 if (markerType
== null){
256 markerType
= (MarkerType
)getTermService().find(uuid
);
257 if (markerType
== null){
258 markerType
= MarkerType
.NewInstance(label
, text
, labelAbbrev
);
259 markerType
.setUuid(uuid
);
261 boolean isOrdered
= false;
262 voc
= getVocabulary(TermType
.MarkerType
, uuidUserDefinedMarkerTypeVocabulary
, "User defined vocabulary for marker types", "User Defined Marker Types", null, null, isOrdered
, markerType
);
264 voc
.addTerm(markerType
);
265 getTermService().save(markerType
);
267 state
.putMarkerType(markerType
);
272 protected AnnotationType
getAnnotationType(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, TermVocabulary
<AnnotationType
> voc
){
274 uuid
= UUID
.randomUUID();
276 AnnotationType annotationType
= state
.getAnnotationType(uuid
);
277 if (annotationType
== null){
278 annotationType
= (AnnotationType
)getTermService().find(uuid
);
279 if (annotationType
== null){
280 annotationType
= AnnotationType
.NewInstance(label
, text
, labelAbbrev
);
281 annotationType
.setUuid(uuid
);
283 boolean isOrdered
= false;
284 voc
= getVocabulary(TermType
.AnnotationType
, uuidUserDefinedAnnotationTypeVocabulary
, "User defined vocabulary for annotation types", "User Defined Annotation Types", null, null, isOrdered
, annotationType
);
287 voc
.addTerm(annotationType
);
288 getTermService().save(annotationType
);
290 state
.putAnnotationType(annotationType
);
292 return annotationType
;
296 protected ReferenceSystem
getReferenceSystem(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, TermVocabulary voc
){
298 uuid
= UUID
.randomUUID();
300 ReferenceSystem refSystem
= state
.getReferenceSystem(uuid
);
301 if (refSystem
== null){
302 refSystem
= (ReferenceSystem
)getTermService().find(uuid
);
303 if (refSystem
== null){
304 refSystem
= ReferenceSystem
.NewInstance(text
, label
, labelAbbrev
);
306 boolean isOrdered
= false;
307 voc
= getVocabulary(TermType
.ReferenceSystem
, uuidUserDefinedReferenceSystemVocabulary
, "User defined vocabulary for reference systems", "User Defined Reference System", null, null, isOrdered
, refSystem
);
309 voc
.addTerm(refSystem
);
310 refSystem
.setUuid(uuid
);
311 getTermService().save(refSystem
);
313 state
.putReferenceSystem(refSystem
);
321 protected Rank
getRank(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
,OrderedTermVocabulary
<Rank
> voc
, Rank lowerRank
, RankClass rankClass
){
323 uuid
= UUID
.randomUUID();
325 Rank rank
= state
.getRank(uuid
);
327 rank
= (Rank
)getTermService().find(uuid
);
329 rank
= Rank
.NewInstance(rankClass
, text
, label
, labelAbbrev
);
331 boolean isOrdered
= true;
332 voc
= (OrderedTermVocabulary
)getVocabulary(TermType
.Rank
, uuidUserDefinedRankVocabulary
, "User defined vocabulary for ranks", "User Defined Reference System", null, null, isOrdered
, rank
);
334 if (lowerRank
== null){
337 voc
.addTermAbove(rank
, lowerRank
);
340 getTermService().save(rank
);
349 * Returns a named area for a given uuid by first . If the named area does not
359 protected NamedArea
getNamedArea(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, NamedAreaType areaType
, NamedAreaLevel level
){
360 return getNamedArea(state
, uuid
, label
, text
, labelAbbrev
, areaType
, level
, null, null);
363 protected NamedArea
getNamedArea(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, NamedAreaType areaType
, NamedAreaLevel level
, TermVocabulary voc
, TermMatchMode matchMode
){
364 return getNamedArea(state
, uuid
, label
, text
, labelAbbrev
, areaType
, level
, voc
, matchMode
, null);
368 protected NamedArea
getNamedArea(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, NamedAreaType areaType
, NamedAreaLevel level
, TermVocabulary voc
, TermMatchMode matchMode
,
369 List
<TermVocabulary
<NamedArea
>> vocabularyPreference
){
370 Class
<NamedArea
> clazz
= NamedArea
.class;
372 uuid
= UUID
.randomUUID();
374 if (matchMode
== null){
375 matchMode
= TermMatchMode
.UUID_ONLY
;
377 NamedArea namedArea
= state
.getNamedArea(uuid
);
378 if (namedArea
== null){
379 DefinedTermBase
<?
> term
= getTermService().find(uuid
);
380 namedArea
= CdmBase
.deproxy(term
,NamedArea
.class);
382 if (vocabularyPreference
== null){
383 vocabularyPreference
= new ArrayList
<TermVocabulary
<NamedArea
>>();
385 if (vocabularyPreference
.isEmpty()){
386 vocabularyPreference
.add(Country
.GERMANY().getVocabulary());
387 vocabularyPreference
.add(TdwgAreaProvider
.getAreaByTdwgAbbreviation("GER").getVocabulary());
391 //TODO matching still experimental
392 if (namedArea
== null && (matchMode
.equals(TermMatchMode
.UUID_LABEL
) || matchMode
.equals(TermMatchMode
.UUID_LABEL_ABBREVLABEL
))){
394 Pager
<NamedArea
> areaPager
= (Pager
)getTermService().findByTitle(clazz
, label
, null, null, null, null, null, null);
395 namedArea
= findBestMatchingArea(areaPager
, uuid
, label
, text
, labelAbbrev
, vocabularyPreference
);
397 if (namedArea
== null && (matchMode
.equals(TermMatchMode
.UUID_ABBREVLABEL
) || matchMode
.equals(TermMatchMode
.UUID_LABEL_ABBREVLABEL
))){
398 Pager
<NamedArea
> areaPager
= getTermService().findByRepresentationAbbreviation(labelAbbrev
, clazz
, null, null);
399 namedArea
= findBestMatchingArea(areaPager
, uuid
, label
, text
, labelAbbrev
, vocabularyPreference
);
402 if (namedArea
== null){
403 namedArea
= NamedArea
.NewInstance(text
, label
, labelAbbrev
);
405 boolean isOrdered
= true;
406 voc
= getVocabulary(TermType
.NamedArea
, uuidUserDefinedNamedAreaVocabulary
, "User defined vocabulary for named areas", "User Defined Named Areas", null, null, isOrdered
, namedArea
);
408 voc
.addTerm(namedArea
);
409 namedArea
.setType(areaType
);
410 namedArea
.setLevel(level
);
411 namedArea
.setUuid(uuid
);
412 getTermService().saveOrUpdate(namedArea
);
414 state
.putNamedArea(namedArea
);
420 private NamedArea
findBestMatchingArea(Pager
<NamedArea
> areaPager
, UUID uuid
, String label
, String text
, String abbrev
, List
<TermVocabulary
<NamedArea
>> vocabularyPreference
) {
421 // TODO preliminary implementation
422 List
<NamedArea
> list
= areaPager
.getRecords();
423 if (list
.size() == 0){
425 }else if (list
.size() == 1){
427 }else if (list
.size() > 1){
428 List
<NamedArea
> preferredList
= new ArrayList
<NamedArea
>();
429 for (TermVocabulary
<NamedArea
> voc
: vocabularyPreference
){
430 for (NamedArea area
: list
){
431 if (voc
.equals(area
.getVocabulary())){
432 preferredList
.add(area
);
435 if (preferredList
.size() > 0){
439 if (preferredList
.size() > 1 ){
440 preferredList
= getLowestLevelAreas(preferredList
);
441 }else if (preferredList
.size() == 0 ){
442 preferredList
= list
;
444 if (preferredList
.size() == 1 ){
445 return preferredList
.get(0);
446 }else if (preferredList
.size() > 1 ){
447 String message
= "There is more than 1 matching area for %s, %s, %s. As a preliminary implementation I take the first";
448 message
= String
.format(message
, label
, abbrev
, text
);
449 logger
.warn(message
);
457 private List
<NamedArea
> getLowestLevelAreas(List
<NamedArea
> preferredList
) {
458 List
<NamedArea
> result
= new ArrayList
<NamedArea
>();
459 for (NamedArea area
: preferredList
){
460 if (result
.isEmpty()){
463 int compare
= compareAreaLevel(area
, result
.get(0));
465 result
= new ArrayList
<NamedArea
>();
467 }else if (compare
== 0){
480 private int compareAreaLevel(NamedArea area1
, NamedArea area2
) {
481 NamedAreaLevel level1
= area1
.getLevel();
482 NamedAreaLevel level2
= area2
.getLevel();
484 return (level2
== null)?
0 : 1;
485 }else if (level2
== null){
488 return level1
.compareTo(level2
);
493 protected NamedAreaLevel
getNamedAreaLevel(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, TermVocabulary
<NamedAreaLevel
> voc
){
495 uuid
= UUID
.randomUUID();
497 NamedAreaLevel namedAreaLevel
= state
.getNamedAreaLevel(uuid
);
498 if (namedAreaLevel
== null){
499 //TODO propPath just for testing
500 List
<String
> propPath
= Arrays
.asList("vocabulary");
501 DefinedTermBase
<NamedAreaLevel
> term
= getTermService().load(uuid
, propPath
);
502 namedAreaLevel
= CdmBase
.deproxy(term
, NamedAreaLevel
.class);
503 if (namedAreaLevel
== null){
504 namedAreaLevel
= NamedAreaLevel
.NewInstance(text
, label
, labelAbbrev
);
506 boolean isOrdered
= true;
507 voc
= getVocabulary(TermType
.NamedAreaLevel
, uuidUserDefinedNamedAreaLevelVocabulary
, "User defined vocabulary for named area levels", "User Defined Named Area Levels", null, null, isOrdered
, namedAreaLevel
);
509 //FIXME only for debugging
510 Set
<NamedAreaLevel
> terms
= voc
.getTerms();
511 for (NamedAreaLevel level
: terms
){
512 TermVocabulary
<NamedAreaLevel
> levelVoc
= level
.getVocabulary();
513 if (levelVoc
== null){
514 logger
.error("ONLY FOR DEBUG: Level voc is null");
516 logger
.info("ONLY FOR DEBUG: Level voc is not null");
519 voc
.addTerm(namedAreaLevel
);
520 namedAreaLevel
.setUuid(uuid
);
521 getTermService().save(namedAreaLevel
);
523 state
.putNamedAreaLevel(namedAreaLevel
);
525 return namedAreaLevel
;
529 * Returns a {@link State} if it exists. <code>null</code> otherwise.
532 * @return {@link State}
534 protected State
getStateTerm(STATE state
, UUID uuid
){
535 return getStateTerm(state
, uuid
, null, null, null, null);
540 * Returns a {@link State} for a given uuid by first checking if the uuid has already been used in this import, if not
541 * checking if the state exists in the database, if not creating it anew (with vocabulary etc.).
542 * If label, text and labelAbbrev are all <code>null</code> no state is created.
551 protected State
getStateTerm(STATE importState
, UUID uuid
, String label
, String text
, String labelAbbrev
, OrderedTermVocabulary
<State
> voc
) {
555 State stateTerm
= importState
.getStateTerm(uuid
);
556 if (stateTerm
== null){
557 stateTerm
= CdmBase
.deproxy(getTermService().find(uuid
), State
.class);
558 if (stateTerm
== null && ! hasNoLabel(label
, text
, labelAbbrev
)){
559 stateTerm
= State
.NewInstance(text
, label
, labelAbbrev
);
560 stateTerm
.setUuid(uuid
);
562 boolean isOrdered
= true;
563 TermVocabulary
<State
> orderedVoc
= getVocabulary(TermType
.State
, uuidUserDefinedStateVocabulary
, "User defined vocabulary for states used by Categorical Data", "User Defined States", null, null, isOrdered
, stateTerm
);
564 voc
= CdmBase
.deproxy(orderedVoc
, OrderedTermVocabulary
.class);
566 voc
.addTerm(stateTerm
);
567 getTermService().save(stateTerm
);
569 logger
.warn("No label provided for new state with uuid " + uuid
);
571 importState
.putStateTerm(stateTerm
);
577 * Returns a feature if it exists, null otherwise.
578 * @see #getFeature(ImportStateBase, UUID, String, String, String, TermVocabulary)
583 protected Feature
getFeature(STATE state
, UUID uuid
){
584 return getFeature(state
, uuid
, null, null, null, null);
588 * Returns a feature for a given uuid by first checking if the uuid has already been used in this import, if not
589 * checking if the feature exists in the database, if not creating it anew (with vocabulary etc.).
590 * If label, text and labelAbbrev are all <code>null</code> no feature is created.
598 protected Feature
getFeature(STATE state
, UUID uuid
, String label
, String description
, String labelAbbrev
, TermVocabulary
<Feature
> voc
){
602 Feature feature
= state
.getFeature(uuid
);
603 if (feature
== null){
604 feature
= (Feature
)getTermService().find(uuid
);
605 if (feature
== null && ! hasNoLabel(label
, description
, labelAbbrev
)){
606 feature
= Feature
.NewInstance(description
, label
, labelAbbrev
);
607 feature
.setUuid(uuid
);
608 feature
.setSupportsTextData(true);
609 // UUID uuidFeatureVoc = UUID.fromString("b187d555-f06f-4d65-9e53-da7c93f8eaa8");
611 boolean isOrdered
= false;
612 voc
= getVocabulary(TermType
.Feature
, uuidUserDefinedFeatureVocabulary
, "User defined vocabulary for features", "User Defined Features", null, null, isOrdered
, feature
);
614 voc
.addTerm(feature
);
615 getTermService().save(feature
);
617 state
.putFeature(feature
);
622 protected DefinedTerm
getKindOfUnit(STATE state
, UUID uuid
, String label
, String description
, String labelAbbrev
, TermVocabulary
<DefinedTerm
> voc
){
626 DefinedTerm unit
= state
.getKindOfUnit(uuid
);
628 unit
= (DefinedTerm
)getTermService().find(uuid
);
629 if (unit
== null && ! hasNoLabel(label
, description
, labelAbbrev
)){
630 unit
= DefinedTerm
.NewKindOfUnitInstance(description
, label
, labelAbbrev
);
633 boolean isOrdered
= false;
634 voc
= getVocabulary(TermType
.KindOfUnit
, uuidUserDefinedKindOfUnitVocabulary
, "User defined vocabulary for kind-of-units", "User Defined Measurement kind-of-units", null, null, isOrdered
, unit
);
637 getTermService().save(unit
);
639 state
.putKindOfUnit(unit
);
645 * Returns a {@link MeasurementUnit} for a given uuid by first checking if the uuid has already been used in this import, if not
646 * checking if the {@link MeasurementUnit} exists in the database, if not creating it anew (with vocabulary etc.).
647 * If label, text and labelAbbrev are all <code>null</code> no {@link MeasurementUnit} is created.
655 protected MeasurementUnit
getMeasurementUnit(STATE state
, UUID uuid
, String label
, String description
, String labelAbbrev
, TermVocabulary
<MeasurementUnit
> voc
){
659 MeasurementUnit unit
= state
.getMeasurementUnit(uuid
);
661 unit
= (MeasurementUnit
)getTermService().find(uuid
);
662 if (unit
== null && ! hasNoLabel(label
, description
, labelAbbrev
)){
663 unit
= MeasurementUnit
.NewInstance(description
, label
, labelAbbrev
);
666 boolean isOrdered
= false;
667 voc
= getVocabulary(TermType
.MeasurementUnit
, uuidUserDefinedMeasurementUnitVocabulary
, "User defined vocabulary for measurement units", "User Defined Measurement Units", null, null, isOrdered
, unit
);
670 getTermService().save(unit
);
672 state
.putMeasurementUnit(unit
);
678 * Returns a {@link StatisticalMeasure} for a given uuid by first checking if the uuid has already been used in this import, if not
679 * checking if the {@link StatisticalMeasure} exists in the database, if not creating it anew (with vocabulary etc.).
680 * If label, text and labelAbbrev are all <code>null</code> no {@link StatisticalMeasure} is created.
688 protected StatisticalMeasure
getStatisticalMeasure(STATE state
, UUID uuid
, String label
, String description
, String labelAbbrev
, TermVocabulary
<StatisticalMeasure
> voc
){
692 StatisticalMeasure statisticalMeasure
= state
.getStatisticalMeasure(uuid
);
693 if (statisticalMeasure
== null){
694 statisticalMeasure
= (StatisticalMeasure
)getTermService().find(uuid
);
695 if (statisticalMeasure
== null && ! hasNoLabel(label
, description
, labelAbbrev
)){
696 statisticalMeasure
= StatisticalMeasure
.NewInstance(description
, label
, labelAbbrev
);
697 statisticalMeasure
.setUuid(uuid
);
699 boolean isOrdered
= false;
700 voc
= getVocabulary(TermType
.StatisticalMeasure
, uuidUserDefinedStatisticalMeasureVocabulary
, "User defined vocabulary for statistical measures", "User Defined Statistical Measures", null, null, isOrdered
, statisticalMeasure
);
702 voc
.addTerm(statisticalMeasure
);
703 getTermService().save(statisticalMeasure
);
705 state
.putStatisticalMeasure(statisticalMeasure
);
707 return statisticalMeasure
;
711 * Returns a {@link Modifier} for a given uuid by first checking if the uuid has already been used in this import, if not
712 * checking if the {@link Modifier} exists in the database, if not creating it anew (with vocabulary etc.).
713 * If label, text and labelAbbrev are all <code>null</code> no {@link Modifier} is created.
721 protected DefinedTerm
getModifier(STATE state
, UUID uuid
, String label
, String description
, String labelAbbrev
, TermVocabulary
<DefinedTerm
> voc
){
725 DefinedTerm modifier
= state
.getModifier(uuid
);
726 if (modifier
== null){
727 modifier
= (DefinedTerm
)getTermService().find(uuid
);
728 if (modifier
== null && ! hasNoLabel(label
, description
, labelAbbrev
)){
729 modifier
= DefinedTerm
.NewModifierInstance(description
, label
, labelAbbrev
);
730 modifier
.setUuid(uuid
);
732 boolean isOrdered
= false;
733 voc
= getVocabulary(TermType
.Modifier
, uuidUserDefinedModifierVocabulary
, "User defined vocabulary for modifier", "User Defined Modifier", null, null, isOrdered
, modifier
);
735 voc
.addTerm(modifier
);
736 getTermService().save(modifier
);
738 state
.putModifier(modifier
);
744 * Returns a taxon relationship type for a given uuid by first checking if the uuid has already been used in this import, if not
745 * checking if the taxon relationship type exists in the database, if not creating it anew (with vocabulary etc.).
746 * If label, text and labelAbbrev are all <code>null</code> no taxon relationship type is created.
754 protected TaxonRelationshipType
getTaxonRelationshipType(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, TermVocabulary
<TaxonRelationshipType
> voc
){
758 TaxonRelationshipType relType
= state
.getTaxonRelationshipType(uuid
);
759 if (relType
== null){
760 relType
= (TaxonRelationshipType
)getTermService().find(uuid
);
761 if (relType
== null && ! hasNoLabel(label
, text
, labelAbbrev
)){
762 relType
= TaxonRelationshipType
.NewInstance(text
, label
, labelAbbrev
, false, false);
763 relType
.setUuid(uuid
);
765 boolean isOrdered
= true;
766 voc
= getVocabulary(TermType
.TaxonRelationshipType
, uuidUserDefinedTaxonRelationshipTypeVocabulary
, "User defined vocabulary for taxon relationship types", "User Defined Taxon Relationship Types", null, null, isOrdered
, relType
);
768 voc
.addTerm(relType
);
769 getTermService().save(relType
);
771 state
.putTaxonRelationshipType(relType
);
776 private boolean hasNoLabel(String label
, String text
, String labelAbbrev
) {
777 return label
== null && text
== null && labelAbbrev
== null;
782 * Returns a presence term for a given uuid by first ...
790 protected PresenceTerm
getPresenceTerm(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
){
794 PresenceTerm presenceTerm
= state
.getPresenceTerm(uuid
);
795 if (presenceTerm
== null){
796 presenceTerm
= (PresenceTerm
)getTermService().find(uuid
);
797 if (presenceTerm
== null){
798 presenceTerm
= PresenceTerm
.NewInstance(text
, label
, labelAbbrev
);
799 presenceTerm
.setUuid(uuid
);
800 //set vocabulary ; FIXME use another user-defined vocabulary
801 UUID uuidPresenceVoc
= UUID
.fromString("adbbbe15-c4d3-47b7-80a8-c7d104e53a05");
802 TermVocabulary
<PresenceTerm
> voc
= getVocabularyService().find(uuidPresenceVoc
);
803 voc
.addTerm(presenceTerm
);
804 getTermService().save(presenceTerm
);
806 state
.putPresenceTerm(presenceTerm
);
812 * Returns a language for a given uuid by first ...
820 protected Language
getLanguage(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
){
821 return getLanguage(state
, uuid
, label
, text
, labelAbbrev
, null);
824 protected Language
getLanguage(STATE state
, UUID uuid
, String label
, String text
, String labelAbbrev
, TermVocabulary voc
){
828 Language language
= state
.getLanguage(uuid
);
829 if (language
== null){
830 language
= (Language
)getTermService().find(uuid
);
831 if (language
== null){
832 language
= Language
.NewInstance(text
, label
, labelAbbrev
);
834 language
.setUuid(uuid
);
836 UUID uuidLanguageVoc
= UUID
.fromString("463a96f1-20ba-4a4c-9133-854c1682bd9b");
837 boolean isOrdered
= false;
838 voc
= getVocabulary(TermType
.Language
, uuidLanguageVoc
, "User defined languages", "User defined languages", "User defined languages", null, isOrdered
, language
);
840 //set vocabulary ; FIXME use another user-defined vocabulary
842 voc
.addTerm(language
);
843 getTermService().save(language
);
845 state
.putLanguage(language
);
856 protected <T
extends DefinedTermBase
> TermVocabulary
<T
> getVocabulary(TermType termType
, UUID uuid
, String description
, String label
, String abbrev
, URI termSourceUri
, boolean isOrdered
, T type
) {
857 List
<String
> propPath
= Arrays
.asList(new String
[]{"terms"});
858 TermVocabulary
<T
> voc
= getVocabularyService().load(uuid
, propPath
);
861 voc
= OrderedTermVocabulary
.NewInstance(termType
, description
, label
, abbrev
, termSourceUri
);
863 voc
= TermVocabulary
.NewInstance(termType
, description
, label
, abbrev
, termSourceUri
);
866 getVocabularyService().save(voc
);
872 * Adds an orginal source to a sourceable objects (implemented for Identifiable entity and description element.
873 * If cdmBase is not sourceable nothing happens.
874 * TODO Move to DbImportBase once this exists.
875 * TODO also implemented in DbImportObjectCreationMapper (reduce redundance)
878 * @param dbIdAttribute
881 * @throws SQLException
883 public void addOriginalSource(CdmBase cdmBase
, Object idAttributeValue
, String namespace
, Reference citation
) {
884 if (cdmBase
instanceof ISourceable
){
885 IOriginalSource source
;
886 ISourceable sourceable
= (ISourceable
<?
>)cdmBase
;
887 Object id
= idAttributeValue
;
888 String strId
= String
.valueOf(id
);
889 String microCitation
= null;
890 OriginalSourceType type
= OriginalSourceType
.Import
;
891 if (cdmBase
instanceof IdentifiableEntity
){
892 source
= IdentifiableSource
.NewInstance(type
, strId
, namespace
, citation
, microCitation
);
893 }else if (cdmBase
instanceof DescriptionElementBase
){
894 source
= DescriptionElementSource
.NewInstance(type
, strId
, namespace
, citation
, microCitation
);
896 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.");
899 sourceable
.addSource(source
);
900 }else if (cdmBase
!= null){
901 logger
.warn("Sourced object does not implement ISourceable: " + cdmBase
.getClass() + "," + cdmBase
.getUuid());
903 logger
.warn("Sourced object is null");
908 * @see #addOriginalSource(CdmBase, Object, String, Reference)
911 * @param dbIdAttribute
914 * @throws SQLException
916 public void addOriginalSource(ResultSet rs
, CdmBase cdmBase
, String dbIdAttribute
, String namespace
, Reference citation
) throws SQLException
{
917 Object id
= rs
.getObject(dbIdAttribute
);
918 addOriginalSource(cdmBase
, id
, namespace
, citation
);
923 * If the child taxon is missing genus or species epithet information and the rank is below <i>genus</i>
924 * or <i>species</i> respectively the according epithets are taken from the parent taxon.
925 * If the name is an autonym and has no combination author/basionym author the authors are taken from
930 protected void fillMissingEpithetsForTaxa(Taxon parentTaxon
, Taxon childTaxon
) {
931 if (parentTaxon
== null){
932 logger
.warn("Parent taxon is null. Missing name parts can not be taken from parent");
935 NonViralName
<?
> parentName
= HibernateProxyHelper
.deproxy(parentTaxon
.getName(), NonViralName
.class);
936 NonViralName
<?
> childName
= HibernateProxyHelper
.deproxy(childTaxon
.getName(), NonViralName
.class);
937 fillMissingEpithets(parentName
, childName
);
941 * If the child name is missing genus or species epithet information and the rank is below <i>genus</i>
942 * or <i>species</i> respectively the according epithets are taken from the parent name.
943 * If the name is an autonym and has no combination author/basionym author the authors are taken from
948 protected void fillMissingEpithets(NonViralName parentName
, NonViralName childName
) {
949 if (StringUtils
.isBlank(childName
.getGenusOrUninomial()) && childName
.getRank().isLower(Rank
.GENUS()) ){
950 childName
.setGenusOrUninomial(parentName
.getGenusOrUninomial());
953 if (StringUtils
.isBlank(childName
.getSpecificEpithet()) && childName
.getRank().isLower(Rank
.SPECIES()) ){
954 childName
.setSpecificEpithet(parentName
.getSpecificEpithet());
956 if (childName
.isAutonym() && childName
.getCombinationAuthorTeam() == null && childName
.getBasionymAuthorTeam() == null ){
957 childName
.setCombinationAuthorTeam(parentName
.getCombinationAuthorTeam());
958 childName
.setBasionymAuthorTeam(parentName
.getBasionymAuthorTeam());
963 * Returns the taxon description for a taxon. If there are multiple taxon descriptions
964 * an arbitrary one is chosen.
965 * If no taxon description exists, a new one is created if <code>createNewIfNotExists</code>
966 * is <code>true</code>.
967 * @param createNewIfNotExists
968 * @param isImageGallery if true only taxon description being image galleries are considered.
969 * If false only taxon description being no image galleries are considered.
972 public TaxonNameDescription
getTaxonNameDescription(TaxonNameBase name
, boolean isImageGallery
, boolean createNewIfNotExists
) {
973 Reference
<?
> ref
= null;
974 return getTaxonNameDescription(name
, ref
, isImageGallery
, createNewIfNotExists
);
978 * Like {@link #getTaxonDescription(Taxon, boolean, boolean)}
979 * Only matches a description if the given reference is a source of the description.<BR>
980 * If a new description is created the given reference will be added as a source.
982 * @see #getTaxonDescription(Taxon, boolean, boolean)
984 public TaxonNameDescription
getTaxonNameDescription(TaxonNameBase
<?
,?
> name
, Reference ref
, boolean isImageGallery
, boolean createNewIfNotExists
) {
985 TaxonNameDescription result
= null;
986 Set
<TaxonNameDescription
> descriptions
= name
.getDescriptions();
987 for (TaxonNameDescription description
: descriptions
){
988 if (description
.isImageGallery() == isImageGallery
){
989 if (hasCorrespondingSource(ref
, description
)){
990 result
= description
;
995 if (result
== null && createNewIfNotExists
){
996 result
= TaxonNameDescription
.NewInstance(name
);
997 result
.setImageGallery(isImageGallery
);
999 result
.addImportSource(null, null, ref
, null);
1006 * Returns the taxon description for a taxon. If there are multiple taxon descriptions
1007 * an arbitrary one is chosen.
1008 * If no taxon description exists, a new one is created if <code>createNewIfNotExists</code>
1009 * is <code>true</code>.
1010 * @param createNewIfNotExists
1011 * @param isImageGallery if true only taxon description being image galleries are considered.
1012 * If false only taxon description being no image galleries are considered.
1015 public TaxonDescription
getTaxonDescription(Taxon taxon
, boolean isImageGallery
, boolean createNewIfNotExists
) {
1016 Reference
<?
> ref
= null;
1017 return getTaxonDescription(taxon
, ref
, isImageGallery
, createNewIfNotExists
);
1021 * Like {@link #getTaxonDescription(Taxon, boolean, boolean)}
1022 * Only matches a description if the given reference is a source of the description.<BR>
1023 * If a new description is created the given reference will be added as a source.
1025 * @see #getTaxonDescription(Taxon, boolean, boolean)
1027 public TaxonDescription
getTaxonDescription(Taxon taxon
, Reference ref
, boolean isImageGallery
, boolean createNewIfNotExists
) {
1028 TaxonDescription result
= null;
1029 Set
<TaxonDescription
> descriptions
= taxon
.getDescriptions();
1030 for (TaxonDescription description
: descriptions
){
1031 if (description
.isImageGallery() == isImageGallery
){
1032 if (hasCorrespondingSource(ref
, description
)){
1033 result
= description
;
1038 if (result
== null && createNewIfNotExists
){
1039 result
= TaxonDescription
.NewInstance(taxon
);
1040 result
.setImageGallery(isImageGallery
);
1042 result
.addImportSource(null, null, ref
, null);
1050 * Returns the {@link SpecimenDescription specimen description} for a {@link SpecimenOrObservationBase specimen or observation}.
1051 * If there are multiple specimen descriptions an arbitrary one is chosen.
1052 * If no specimen description exists, a new one is created if <code>createNewIfNotExists</code> is <code>true</code>.
1053 * @param createNewIfNotExists
1054 * @param isImageGallery if true only specimen description being image galleries are considered.
1055 * If false only specimen description being no image galleries are considered.
1058 public SpecimenDescription
getSpecimenDescription(SpecimenOrObservationBase specimen
, boolean isImageGallery
, boolean createNewIfNotExists
) {
1059 Reference ref
= null;
1060 return getSpecimenDescription(specimen
, ref
, isImageGallery
, createNewIfNotExists
);
1064 * Like {@link #getSpecimenDescription(SpecimenOrObservationBase, boolean, boolean)}
1065 * Only matches a description if the given reference is a source of the description.<BR>
1066 * If a new description is created the given reference will be added as a source.
1068 * @see #getTaxonDescription(Taxon, boolean, boolean)
1070 public SpecimenDescription
getSpecimenDescription(SpecimenOrObservationBase specimen
, Reference ref
, boolean isImageGallery
, boolean createNewIfNotExists
) {
1071 SpecimenDescription result
= null;
1072 Set
<SpecimenDescription
> descriptions
= specimen
.getDescriptions();
1073 for (SpecimenDescription description
: descriptions
){
1074 if (description
.isImageGallery() == isImageGallery
){
1075 if (hasCorrespondingSource(ref
, description
)){
1076 result
= description
;
1081 if (result
== null && createNewIfNotExists
){
1082 result
= SpecimenDescription
.NewInstance(specimen
);
1083 result
.setImageGallery(isImageGallery
);
1085 result
.addImportSource(null, null, ref
, null);
1093 * Returns the textdata that holds general information about a feature for a taxon description.
1094 * This is mainly necessary for descriptions that have more than one description element for
1095 * a given feature such as 'distribution', 'description' or 'common name'. It may also hold
1096 * for hierarchical features where no description element exists for a higher hierarchy level.
1097 * Example: the description feature has subfeatures. But some information like authorship, figures,
1098 * sources need to be added to the description itself.
1099 * Currently a feature placeholder is marked by a marker of type 'feature placeholder'. Maybe in future
1100 * there will be a boolean marker in the TextData class itself.
1105 * @param createIfNotExists
1108 protected TextData
getFeaturePlaceholder(STATE state
, DescriptionBase
<?
> description
, Feature feature
, boolean createIfNotExists
) {
1109 UUID featurePlaceholderUuid
= MarkupTransformer
.uuidFeaturePlaceholder
;
1110 for (DescriptionElementBase element
: description
.getElements()){
1111 if (element
.isInstanceOf(TextData
.class)){
1112 TextData textData
= CdmBase
.deproxy(element
, TextData
.class);
1113 if (textData
.getFeature() == null || ! textData
.getFeature().equals(feature
)){
1116 for (Marker marker
: textData
.getMarkers()){
1117 MarkerType markerType
= marker
.getMarkerType();
1118 if (markerType
!= null &&
1119 markerType
.getUuid().equals(featurePlaceholderUuid
) &&
1120 marker
.getValue() == true){
1126 if (createIfNotExists
){
1127 TextData newPlaceholder
= TextData
.NewInstance(feature
);
1128 MarkerType placeholderMarkerType
= getMarkerType(state
, featurePlaceholderUuid
, "Feature Placeholder", "Feature Placeholder", null);
1129 Marker marker
= Marker
.NewInstance(placeholderMarkerType
, true);
1130 newPlaceholder
.addMarker(marker
);
1131 description
.addElement(newPlaceholder
);
1132 return newPlaceholder
;
1141 * Returns true, if this description has a source with a citation equal to the given reference.
1142 * Returns true if the given reference is null.
1144 * @param description
1146 private boolean hasCorrespondingSource(Reference
<?
> ref
, DescriptionBase
<?
> description
) {
1148 for (IdentifiableSource source
: description
.getSources()){
1149 if (ref
.equals(source
.getCitation())){
1161 * Returns the accepted taxon of a {@link TaxonBase taxon base}. <BR>
1162 * If taxonBase is of type taxon the same object is returned. If taxonBase is of type
1163 * synonym the accepted taxon is returned if one exists. If no accepted taxon exists
1164 * <code>null</code> is returned. If multiple accepted taxa exist the one taxon with the
1165 * same secundum reference is returned. If no such single taxon exists an
1166 * {@link IllegalStateException illegal state exception} is thrown.
1170 protected Taxon
getAcceptedTaxon(TaxonBase
<?
> taxonBase
) {
1171 if (taxonBase
== null){
1173 }else if(taxonBase
.isInstanceOf(Taxon
.class)){
1174 return CdmBase
.deproxy(taxonBase
, Taxon
.class);
1175 }else if(taxonBase
.isInstanceOf(Synonym
.class)){
1176 Synonym synonym
= CdmBase
.deproxy(taxonBase
, Synonym
.class);
1177 Set
<Taxon
> acceptedTaxa
= synonym
.getAcceptedTaxa();
1178 if (acceptedTaxa
.size() == 0){
1180 }else if (acceptedTaxa
.size() == 1){
1181 return acceptedTaxa
.iterator().next();
1183 Reference
<?
> sec
= synonym
.getSec();
1185 Set
<Taxon
> taxaWithSameSec
= new HashSet
<Taxon
>();
1186 for (Taxon taxon
: acceptedTaxa
){
1187 if (sec
.equals(taxon
.getSec())){
1188 taxaWithSameSec
.add(taxon
);
1191 if (taxaWithSameSec
.size() == 1){
1192 return taxaWithSameSec
.iterator().next();
1195 throw new IllegalStateException("Can't define the one accepted taxon for a synonym out of multiple accept taxa");
1198 throw new IllegalStateException("Unknown TaxonBase subclass: " + taxonBase
.getClass().getName());
1207 * @param readDataFromUrl
1208 * @see #READ_MEDIA_DATA
1210 * @throws MalformedURLException
1212 protected Media
getImageMedia(String uriString
, boolean readMediaData
) throws MalformedURLException
{
1213 if( uriString
== null){
1216 ImageInfo imageInfo
= null;
1218 uriString
= uriString
.replace(" ", "%20"); //replace whitespace
1220 uri
= new URI(uriString
);
1224 imageInfo
= ImageInfo
.NewInstance(uri
, 0);
1226 } catch (Exception e
) {
1227 String message
= "An error occurred when trying to read image meta data for " + uri
.toString() + ": " + e
.getMessage();
1228 logger
.warn(message
);
1229 fireWarningEvent(message
, "unknown location", 2, 0);
1231 ImageFile imageFile
= ImageFile
.NewInstance(uri
, null, imageInfo
);
1232 MediaRepresentation representation
= MediaRepresentation
.NewInstance();
1233 if(imageInfo
!= null){
1234 representation
.setMimeType(imageInfo
.getMimeType());
1235 representation
.setSuffix(imageInfo
.getSuffix());
1237 representation
.addRepresentationPart(imageFile
);
1238 Media media
= Media
.NewInstance();
1239 media
.addRepresentation(representation
);
1241 } catch (URISyntaxException e1
) {
1242 String message
= "An URISyntaxException occurred when trying to create uri from multimedia objcet string: " + uriString
;
1243 logger
.warn(message
);
1244 fireWarningEvent(message
, "unknown location", 4, 0);
1252 * Retrieves an Integer value from a result set. If the value is NULL null is returned.
1253 * ResultSet.getInt() returns 0 therefore we need a special handling for this case.
1257 * @throws SQLException
1259 protected Integer
nullSafeInt(ResultSet rs
, String columnName
) throws SQLException
{
1260 Object intObject
= rs
.getObject(columnName
);
1261 if (intObject
== null){
1264 return Integer
.valueOf(intObject
.toString());
1268 protected Boolean
nullSafeBoolean(ResultSet rs
, String columnName
) throws SQLException
{
1269 Object bitObject
= rs
.getObject(columnName
);
1270 if (bitObject
== null){
1273 return Boolean
.valueOf(bitObject
.toString());
1277 protected Double
nullSafeDouble(ResultSet rs
, String columnName
) throws SQLException
{
1278 Object doubleObject
= rs
.getObject(columnName
);
1279 if (doubleObject
== null){
1282 return Double
.valueOf(doubleObject
.toString());
1286 protected Float
nullSafeFloat(ResultSet rs
, String columnName
) throws SQLException
{
1287 Object doubleObject
= rs
.getObject(columnName
);
1288 if (doubleObject
== null){
1291 return Float
.valueOf(doubleObject
.toString());
1297 * Returns <code>null</code> for all blank strings. Identity function otherwise.
1301 protected String
NB(String str
) {
1302 if (StringUtils
.isBlank(str
)){