update factory methods for original sources #1549
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / common / CdmImportBase.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.cdm.io.common;
11
12 import java.net.MalformedURLException;
13 import java.net.URI;
14 import java.net.URISyntaxException;
15 import java.sql.ResultSet;
16 import java.sql.SQLException;
17 import java.util.Arrays;
18 import java.util.HashSet;
19 import java.util.List;
20 import java.util.Set;
21 import java.util.UUID;
22
23 import org.apache.commons.lang.StringUtils;
24 import org.apache.log4j.Logger;
25
26 import eu.etaxonomy.cdm.api.service.pager.Pager;
27 import eu.etaxonomy.cdm.common.media.ImageInfo;
28 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
29 import eu.etaxonomy.cdm.io.common.mapping.IInputTransformer;
30 import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
31 import eu.etaxonomy.cdm.io.markup.MarkupTransformer;
32 import eu.etaxonomy.cdm.model.common.AnnotationType;
33 import eu.etaxonomy.cdm.model.common.CdmBase;
34 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
35 import eu.etaxonomy.cdm.model.common.DescriptionElementSource;
36 import eu.etaxonomy.cdm.model.common.ExtensionType;
37 import eu.etaxonomy.cdm.model.common.Figure;
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.Representation;
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.Feature;
52 import eu.etaxonomy.cdm.model.description.MeasurementUnit;
53 import eu.etaxonomy.cdm.model.description.Modifier;
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.NamedArea;
62 import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
63 import eu.etaxonomy.cdm.model.location.NamedAreaType;
64 import eu.etaxonomy.cdm.model.location.ReferenceSystem;
65 import eu.etaxonomy.cdm.model.media.ImageFile;
66 import eu.etaxonomy.cdm.model.media.Media;
67 import eu.etaxonomy.cdm.model.media.MediaRepresentation;
68 import eu.etaxonomy.cdm.model.name.NonViralName;
69 import eu.etaxonomy.cdm.model.name.Rank;
70 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
71 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
72 import eu.etaxonomy.cdm.model.reference.Reference;
73 import eu.etaxonomy.cdm.model.taxon.Classification;
74 import eu.etaxonomy.cdm.model.taxon.Synonym;
75 import eu.etaxonomy.cdm.model.taxon.Taxon;
76 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
77 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
78
79 /**
80 * @author a.mueller
81 * @created 01.07.2008
82 * @version 1.0
83 */
84 public abstract class CdmImportBase<CONFIG extends IImportConfigurator, STATE extends ImportStateBase> extends CdmIoBase<STATE> implements ICdmImport<CONFIG, STATE>{
85 private static Logger logger = Logger.getLogger(CdmImportBase.class);
86
87 protected static final boolean CREATE = true;
88 protected static final boolean IMAGE_GALLERY = true;
89 protected static final boolean READ_MEDIA_DATA = true;
90
91 public static final UUID uuidUserDefinedNamedAreaLevelVocabulary = UUID.fromString("255144da-8d95-457e-a327-9752a8f85e5a");
92 public static final UUID uuidUserDefinedNamedAreaVocabulary = UUID.fromString("b2238399-a3af-4f6d-b7eb-ff5d0899bf1b");
93 public static final UUID uuidUserDefinedExtensionTypeVocabulary = UUID.fromString("e28c1394-1be8-4847-8b81-ab44eb6d5bc8");
94 public static final UUID uuidUserDefinedReferenceSystemVocabulary = UUID.fromString("467591a3-10b4-4bf1-9239-f06ece33e90a");
95 public static final UUID uuidUserDefinedFeatureVocabulary = UUID.fromString("fe5fccb3-a2f2-4b97-b199-6e2743cf1627");
96 public static final UUID uuidUserDefinedMeasurementUnitVocabulary = UUID.fromString("d5e72bb7-f312-4080-bb86-c695d04a6e66");
97 public static final UUID uuidUserDefinedStatisticalMeasureVocabulary = UUID.fromString("62a89836-c730-4b4f-a904-3d859dbfc400");
98 public static final UUID uuidUserDefinedStateVocabulary = UUID.fromString("f7cddb49-8392-4db1-8640-65b48a0e6d13");
99 public static final UUID uuidUserDefinedTaxonRelationshipTypeVocabulary = UUID.fromString("31a324dc-408d-4877-891f-098db21744c6");
100 public static final UUID uuidUserDefinedAnnotationTypeVocabulary = UUID.fromString("cd9ecdd2-9cae-4890-9032-ad83293ae883");
101 public static final UUID uuidUserDefinedMarkerTypeVocabulary = UUID.fromString("5f02a261-fd7d-4fce-bbe4-21472de8cd51");
102 public static final UUID uuidUserDefinedRankVocabulary = UUID.fromString("4dc57931-38e2-46c3-974d-413b087646ba");
103
104 public static final UUID uuidUserDefinedModifierVocabulary = UUID.fromString("2a8b3838-3a95-49ea-9ab2-3049614b5884");
105
106
107
108 private static final String UuidOnly = "UUIDOnly";
109 private static final String UuidLabel = "UUID or label";
110 private static final String UuidLabelAbbrev = "UUID, label or abbreviation";
111 private static final String UuidAbbrev = "UUID or abbreviation";
112
113 public enum TermMatchMode{
114 UUID_ONLY(0, UuidOnly)
115 ,UUID_LABEL(1, UuidLabel)
116 ,UUID_LABEL_ABBREVLABEL(2, UuidLabelAbbrev)
117 ,UUID_ABBREVLABEL(3, UuidAbbrev)
118 ;
119
120
121 private int id;
122 private String representation;
123 private TermMatchMode(int id, String representation){
124 this.id = id;
125 this.representation = representation;
126 }
127 public int getId() {
128 return id;
129 }
130 public String getRepresentation() {
131 return representation;
132 }
133 public TermMatchMode valueOf(int id){
134 switch (id){
135 case 0: return UUID_ONLY;
136 case 1: return UUID_LABEL;
137 case 2: return UUID_LABEL_ABBREVLABEL;
138 case 3: return UUID_ABBREVLABEL;
139 default: return UUID_ONLY;
140 }
141 }
142
143
144 }
145
146 protected Classification makeTree(STATE state, Reference reference){
147 String treeName = "Classification (Import)";
148 if (reference != null && StringUtils.isNotBlank(reference.getTitleCache())){
149 treeName = reference.getTitleCache();
150 }
151 Classification tree = Classification.NewInstance(treeName);
152 tree.setReference(reference);
153
154
155 // use defined uuid for first tree
156 CONFIG config = (CONFIG)state.getConfig();
157 if (state.countTrees() < 1 ){
158 tree.setUuid(config.getClassificationUuid());
159 }
160 getClassificationService().save(tree);
161 state.putTree(reference, tree);
162 return tree;
163 }
164
165
166 /**
167 * Alternative memory saving method variant of
168 * {@link #makeTree(STATE state, Reference ref)} which stores only the
169 * UUID instead of the full tree in the <code>ImportStateBase</code> by
170 * using <code>state.putTreeUuid(ref, tree);</code>
171 *
172 * @param state
173 * @param ref
174 * @return
175 */
176 protected Classification makeTreeMemSave(STATE state, Reference ref){
177 String treeName = "Classification (Import)";
178 if (ref != null && StringUtils.isNotBlank(ref.getTitleCache())){
179 treeName = ref.getTitleCache();
180 }
181 Classification tree = Classification.NewInstance(treeName);
182 tree.setReference(ref);
183
184
185 // use defined uuid for first tree
186 CONFIG config = (CONFIG)state.getConfig();
187 if (state.countTrees() < 1 ){
188 tree.setUuid(config.getClassificationUuid());
189 }
190 getClassificationService().save(tree);
191 state.putTreeUuid(ref, tree);
192 return tree;
193 }
194
195
196 protected ExtensionType getExtensionType(STATE state, UUID uuid, String label, String text, String labelAbbrev){
197 return getExtensionType(state, uuid, label, text, labelAbbrev, null);
198 }
199 protected ExtensionType getExtensionType(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary<ExtensionType> voc){
200 if (uuid == null){
201 uuid = UUID.randomUUID();
202 }
203 ExtensionType extensionType = state.getExtensionType(uuid);
204 if (extensionType == null){
205 extensionType = (ExtensionType)getTermService().find(uuid);
206 if (extensionType == null){
207 extensionType = ExtensionType.NewInstance(text, label, labelAbbrev);
208 extensionType.setUuid(uuid);
209 if (voc == null){
210 boolean isOrdered = false;
211 voc = getVocabulary(uuidUserDefinedExtensionTypeVocabulary, "User defined vocabulary for extension types", "User Defined Extension Types", null, null, isOrdered, extensionType);
212 }
213 voc.addTerm(extensionType);
214 getTermService().saveOrUpdate(extensionType);
215 }
216 state.putExtensionType(extensionType);
217 }
218 return extensionType;
219 }
220
221
222 protected MarkerType getMarkerType(STATE state, String keyString) {
223 IInputTransformer transformer = state.getTransformer();
224 MarkerType markerType = null;
225 try {
226 markerType = transformer.getMarkerTypeByKey(keyString);
227 } catch (UndefinedTransformerMethodException e) {
228 logger.info("getMarkerTypeByKey not yet implemented for this import");
229 }
230 if (markerType == null ){
231 UUID uuid;
232 try {
233 uuid = transformer.getMarkerTypeUuid(keyString);
234 return getMarkerType(state, uuid, keyString, keyString, keyString);
235 } catch (UndefinedTransformerMethodException e) {
236 logger.warn("getMarkerTypeUuid not yet implemented for this import");
237 }
238 }
239 return null;
240 }
241
242 protected MarkerType getMarkerType(STATE state, UUID uuid, String label, String text, String labelAbbrev){
243 return getMarkerType(state, uuid, label, text, labelAbbrev, null);
244 }
245
246
247 protected MarkerType getMarkerType(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary<MarkerType> voc){
248 if (uuid == null){
249 uuid = UUID.randomUUID();
250 }
251 MarkerType markerType = state.getMarkerType(uuid);
252 if (markerType == null){
253 markerType = (MarkerType)getTermService().find(uuid);
254 if (markerType == null){
255 markerType = MarkerType.NewInstance(label, text, labelAbbrev);
256 markerType.setUuid(uuid);
257 if (voc == null){
258 boolean isOrdered = false;
259 voc = getVocabulary(uuidUserDefinedMarkerTypeVocabulary, "User defined vocabulary for marker types", "User Defined Marker Types", null, null, isOrdered, markerType);
260 }
261 voc.addTerm(markerType);
262 getTermService().save(markerType);
263 }
264 state.putMarkerType(markerType);
265 }
266 return markerType;
267 }
268
269 protected AnnotationType getAnnotationType(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary<AnnotationType> voc){
270 if (uuid == null){
271 uuid = UUID.randomUUID();
272 }
273 AnnotationType annotationType = state.getAnnotationType(uuid);
274 if (annotationType == null){
275 annotationType = (AnnotationType)getTermService().find(uuid);
276 if (annotationType == null){
277 annotationType = AnnotationType.NewInstance(label, text, labelAbbrev);
278 annotationType.setUuid(uuid);
279 if (voc == null){
280 boolean isOrdered = false;
281 voc = getVocabulary(uuidUserDefinedAnnotationTypeVocabulary, "User defined vocabulary for annotation types", "User Defined Annotation Types", null, null, isOrdered, annotationType);
282 }
283
284 voc.addTerm(annotationType);
285 getTermService().save(annotationType);
286 }
287 state.putAnnotationType(annotationType);
288 }
289 return annotationType;
290 }
291
292
293 protected ReferenceSystem getReferenceSystem(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary voc){
294 if (uuid == null){
295 uuid = UUID.randomUUID();
296 }
297 ReferenceSystem refSystem = state.getReferenceSystem(uuid);
298 if (refSystem == null){
299 refSystem = (ReferenceSystem)getTermService().find(uuid);
300 if (refSystem == null){
301 refSystem = ReferenceSystem.NewInstance(text, label, labelAbbrev);
302 if (voc == null){
303 boolean isOrdered = false;
304 voc = getVocabulary(uuidUserDefinedReferenceSystemVocabulary, "User defined vocabulary for reference systems", "User Defined Reference System", null, null, isOrdered, refSystem);
305 }
306 voc.addTerm(refSystem);
307 refSystem.setUuid(uuid);
308 getTermService().save(refSystem);
309 }
310 state.putReferenceSystem(refSystem);
311 }
312 return refSystem;
313
314 }
315
316
317
318 protected Rank getRank(STATE state, UUID uuid, String label, String text, String labelAbbrev,OrderedTermVocabulary<Rank> voc, Rank lowerRank){
319 if (uuid == null){
320 uuid = UUID.randomUUID();
321 }
322 Rank rank = state.getRank(uuid);
323 if (rank == null){
324 rank = (Rank)getTermService().find(uuid);
325 if (rank == null){
326 rank = new Rank(text, label, labelAbbrev);
327 if (voc == null){
328 boolean isOrdered = true;
329 voc = (OrderedTermVocabulary)getVocabulary(uuidUserDefinedRankVocabulary, "User defined vocabulary for ranks", "User Defined Reference System", null, null, isOrdered, rank);
330 }
331 if (lowerRank == null){
332 voc.addTerm(rank);
333 }else{
334 voc.addTermAbove(rank, lowerRank);
335 }
336 rank.setUuid(uuid);
337 getTermService().save(rank);
338 }
339 state.putRank(rank);
340 }
341 return rank;
342
343 }
344
345 /**
346 * Returns a named area for a given uuid by first . If the named area does not
347 * @param state
348 * @param uuid
349 * @param label
350 * @param text
351 * @param labelAbbrev
352 * @param areaType
353 * @param level
354 * @return
355 */
356 protected NamedArea getNamedArea(STATE state, UUID uuid, String label, String text, String labelAbbrev, NamedAreaType areaType, NamedAreaLevel level){
357 return getNamedArea(state, uuid, label, text, labelAbbrev, areaType, level, null, null);
358 }
359
360 protected NamedArea getNamedArea(STATE state, UUID uuid, String label, String text, String labelAbbrev, NamedAreaType areaType, NamedAreaLevel level, TermVocabulary voc, TermMatchMode matchMode){
361 Class<NamedArea> clazz = NamedArea.class;
362 if (uuid == null){
363 uuid = UUID.randomUUID();
364 }
365 if (matchMode == null){
366 matchMode = TermMatchMode.UUID_ONLY;
367 }
368 NamedArea namedArea = state.getNamedArea(uuid);
369 if (namedArea == null){
370 DefinedTermBase<?> term = getTermService().find(uuid);
371 namedArea = CdmBase.deproxy(term,NamedArea.class);
372 //TODO matching still experimental
373 if (namedArea == null && (matchMode.equals(TermMatchMode.UUID_LABEL) || matchMode.equals(TermMatchMode.UUID_LABEL_ABBREVLABEL ))){
374 //TODO test
375 Pager<NamedArea> areaPager = (Pager)getTermService().findByTitle(clazz, label, null, null, null, null, null, null);
376 namedArea = findBestMatchingArea(areaPager, uuid, label, text, labelAbbrev, areaType, level, voc);
377 }
378 if (namedArea == null && (matchMode.equals(TermMatchMode.UUID_ABBREVLABEL) || matchMode.equals(TermMatchMode.UUID_LABEL_ABBREVLABEL))){
379 Pager<NamedArea> areaPager = getTermService().findByRepresentationAbbreviation(labelAbbrev, clazz, null, null);
380 namedArea = findBestMatchingArea(areaPager, uuid, label, text, labelAbbrev, areaType, level, voc);
381 }
382
383 if (namedArea == null){
384 namedArea = NamedArea.NewInstance(text, label, labelAbbrev);
385 if (voc == null){
386 boolean isOrdered = true;
387 voc = getVocabulary(uuidUserDefinedNamedAreaVocabulary, "User defined vocabulary for named areas", "User Defined Named Areas", null, null, isOrdered, namedArea);
388 }
389 voc.addTerm(namedArea);
390 namedArea.setType(areaType);
391 namedArea.setLevel(level);
392 namedArea.setUuid(uuid);
393 getTermService().save(namedArea);
394 }
395 state.putNamedArea(namedArea);
396 }
397 return namedArea;
398 }
399
400
401 private NamedArea findBestMatchingArea(Pager<NamedArea> areaPager, UUID uuid, String label, String text, String abbrev,
402 NamedAreaType areaType, NamedAreaLevel level, TermVocabulary voc) {
403 // TODO preliminary implementation
404 List<NamedArea> list = areaPager.getRecords();
405 if (list.size() == 0){
406 return null;
407 }else if (list.size() == 1){
408 return list.get(0);
409 }else if (list.size() > 1){
410 String message = "There is more than 1 matching area for %s, %s, %s. As a preliminary implementation I take the first";
411 message = String.format(message, label, abbrev, text);
412 logger.warn(message);
413 return list.get(0);
414 }
415 return null;
416 }
417
418
419 protected NamedAreaLevel getNamedAreaLevel(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary<NamedAreaLevel> voc){
420 if (uuid == null){
421 uuid = UUID.randomUUID();
422 }
423 NamedAreaLevel namedAreaLevel = state.getNamedAreaLevel(uuid);
424 if (namedAreaLevel == null){
425 //TODO propPath just for testing
426 List<String> propPath = Arrays.asList("vocabulary");
427 DefinedTermBase<NamedAreaLevel> term = getTermService().load(uuid, propPath);
428 namedAreaLevel = CdmBase.deproxy(term, NamedAreaLevel.class);
429 if (namedAreaLevel == null){
430 namedAreaLevel = NamedAreaLevel.NewInstance(text, label, labelAbbrev);
431 if (voc == null){
432 boolean isOrdered = true;
433 voc = getVocabulary(uuidUserDefinedNamedAreaLevelVocabulary, "User defined vocabulary for named area levels", "User Defined Named Area Levels", null, null, isOrdered, namedAreaLevel);
434 }
435 //FIXME only for debugging
436 Set<NamedAreaLevel> terms = voc.getTerms();
437 for (NamedAreaLevel level : terms){
438 TermVocabulary<NamedAreaLevel> levelVoc = level.getVocabulary();
439 if (levelVoc == null){
440 logger.error("ONLY FOR DEBUG: Level voc is null");
441 }else{
442 logger.info("ONLY FOR DEBUG: Level voc is not null");
443 }
444 }
445 voc.addTerm(namedAreaLevel);
446 namedAreaLevel.setUuid(uuid);
447 getTermService().save(namedAreaLevel);
448 }
449 state.putNamedAreaLevel(namedAreaLevel);
450 }
451 return namedAreaLevel;
452 }
453
454 /**
455 * Returns a {@link State} if it exists. <code>null</code> otherwise.
456 * @param state
457 * @param uuid
458 * @return {@link State}
459 */
460 protected State getStateTerm(STATE state, UUID uuid){
461 return getStateTerm(state, uuid, null, null, null, null);
462 }
463
464
465 /**
466 * Returns a {@link State} for a given uuid by first checking if the uuid has already been used in this import, if not
467 * checking if the state exists in the database, if not creating it anew (with vocabulary etc.).
468 * If label, text and labelAbbrev are all <code>null</code> no state is created.
469 * @param importState
470 * @param uuid
471 * @param label
472 * @param text
473 * @param labelAbbrev
474 * @param voc
475 * @return
476 */
477 protected State getStateTerm(STATE importState, UUID uuid, String label, String text, String labelAbbrev, OrderedTermVocabulary<State> voc) {
478 if (uuid == null){
479 return null;
480 }
481 State stateTerm = importState.getStateTerm(uuid);
482 if (stateTerm == null){
483 stateTerm = CdmBase.deproxy(getTermService().find(uuid), State.class);
484 if (stateTerm == null && ! hasNoLabel(label, text, labelAbbrev)){
485 stateTerm = State.NewInstance(text, label, labelAbbrev);
486 stateTerm.setUuid(uuid);
487 if (voc == null){
488 boolean isOrdered = true;
489 TermVocabulary<State> orderedVoc = getVocabulary(uuidUserDefinedStateVocabulary, "User defined vocabulary for states used by Categorical Data", "User Defined States", null, null, isOrdered, stateTerm);
490 voc = CdmBase.deproxy(orderedVoc, OrderedTermVocabulary.class);
491 }
492 voc.addTerm(stateTerm);
493 getTermService().save(stateTerm);
494 }else{
495 logger.warn("No label provided for new state with uuid " + uuid);
496 }
497 importState.putStateTerm(stateTerm);
498 }
499 return stateTerm;
500 }
501
502 /**
503 * Returns a feature if it exists, null otherwise.
504 * @see #getFeature(ImportStateBase, UUID, String, String, String, TermVocabulary)
505 * @param state
506 * @param uuid
507 * @return
508 */
509 protected Feature getFeature(STATE state, UUID uuid){
510 return getFeature(state, uuid, null, null, null, null);
511 }
512
513 /**
514 * Returns a feature for a given uuid by first checking if the uuid has already been used in this import, if not
515 * checking if the feature exists in the database, if not creating it anew (with vocabulary etc.).
516 * If label, text and labelAbbrev are all <code>null</code> no feature is created.
517 * @param state
518 * @param uuid
519 * @param label
520 * @param text
521 * @param labelAbbrev
522 * @return
523 */
524 protected Feature getFeature(STATE state, UUID uuid, String label, String description, String labelAbbrev, TermVocabulary<Feature> voc){
525 if (uuid == null){
526 return null;
527 }
528 Feature feature = state.getFeature(uuid);
529 if (feature == null){
530 feature = (Feature)getTermService().find(uuid);
531 if (feature == null && ! hasNoLabel(label, description, labelAbbrev)){
532 feature = Feature.NewInstance(description, label, labelAbbrev);
533 feature.setUuid(uuid);
534 feature.setSupportsTextData(true);
535 // UUID uuidFeatureVoc = UUID.fromString("b187d555-f06f-4d65-9e53-da7c93f8eaa8");
536 if (voc == null){
537 boolean isOrdered = false;
538 voc = getVocabulary(uuidUserDefinedFeatureVocabulary, "User defined vocabulary for features", "User Defined Features", null, null, isOrdered, feature);
539 }
540 voc.addTerm(feature);
541 getTermService().save(feature);
542 }
543 state.putFeature(feature);
544 }
545 return feature;
546 }
547
548 /**
549 * Returns a {@link MeasurementUnit} for a given uuid by first checking if the uuid has already been used in this import, if not
550 * checking if the {@link MeasurementUnit} exists in the database, if not creating it anew (with vocabulary etc.).
551 * If label, text and labelAbbrev are all <code>null</code> no {@link MeasurementUnit} is created.
552 * @param state
553 * @param uuid
554 * @param label
555 * @param text
556 * @param labelAbbrev
557 * @return
558 */
559 protected MeasurementUnit getMeasurementUnit(STATE state, UUID uuid, String label, String description, String labelAbbrev, TermVocabulary<MeasurementUnit> voc){
560 if (uuid == null){
561 return null;
562 }
563 MeasurementUnit unit = state.getMeasurementUnit(uuid);
564 if (unit == null){
565 unit = (MeasurementUnit)getTermService().find(uuid);
566 if (unit == null && ! hasNoLabel(label, description, labelAbbrev)){
567 unit = MeasurementUnit.NewInstance(description, label, labelAbbrev);
568 unit.setUuid(uuid);
569 if (voc == null){
570 boolean isOrdered = false;
571 voc = getVocabulary(uuidUserDefinedMeasurementUnitVocabulary, "User defined vocabulary for measurement units", "User Defined Measurement Units", null, null, isOrdered, unit);
572 }
573 voc.addTerm(unit);
574 getTermService().save(unit);
575 }
576 state.putMeasurementUnit(unit);
577 }
578 return unit;
579 }
580
581 /**
582 * Returns a {@link StatisticalMeasure} for a given uuid by first checking if the uuid has already been used in this import, if not
583 * checking if the {@link StatisticalMeasure} exists in the database, if not creating it anew (with vocabulary etc.).
584 * If label, text and labelAbbrev are all <code>null</code> no {@link StatisticalMeasure} is created.
585 * @param state
586 * @param uuid
587 * @param label
588 * @param text
589 * @param labelAbbrev
590 * @return
591 */
592 protected StatisticalMeasure getStatisticalMeasure(STATE state, UUID uuid, String label, String description, String labelAbbrev, TermVocabulary<StatisticalMeasure> voc){
593 if (uuid == null){
594 return null;
595 }
596 StatisticalMeasure statisticalMeasure = state.getStatisticalMeasure(uuid);
597 if (statisticalMeasure == null){
598 statisticalMeasure = (StatisticalMeasure)getTermService().find(uuid);
599 if (statisticalMeasure == null && ! hasNoLabel(label, description, labelAbbrev)){
600 statisticalMeasure = StatisticalMeasure.NewInstance(description, label, labelAbbrev);
601 statisticalMeasure.setUuid(uuid);
602 if (voc == null){
603 boolean isOrdered = false;
604 voc = getVocabulary(uuidUserDefinedStatisticalMeasureVocabulary, "User defined vocabulary for statistical measures", "User Defined Statistical Measures", null, null, isOrdered, statisticalMeasure);
605 }
606 voc.addTerm(statisticalMeasure);
607 getTermService().save(statisticalMeasure);
608 }
609 state.putStatisticalMeasure(statisticalMeasure);
610 }
611 return statisticalMeasure;
612 }
613
614 /**
615 * Returns a {@link Modifier} for a given uuid by first checking if the uuid has already been used in this import, if not
616 * checking if the {@link Modifier} exists in the database, if not creating it anew (with vocabulary etc.).
617 * If label, text and labelAbbrev are all <code>null</code> no {@link Modifier} is created.
618 * @param state
619 * @param uuid
620 * @param label
621 * @param text
622 * @param labelAbbrev
623 * @return
624 */
625 protected Modifier getModifier(STATE state, UUID uuid, String label, String description, String labelAbbrev, TermVocabulary<Modifier> voc){
626 if (uuid == null){
627 return null;
628 }
629 Modifier modifier = state.getModifier(uuid);
630 if (modifier == null){
631 modifier = (Modifier)getTermService().find(uuid);
632 if (modifier == null && ! hasNoLabel(label, description, labelAbbrev)){
633 modifier = Modifier.NewInstance(description, label, labelAbbrev);
634 modifier.setUuid(uuid);
635 if (voc == null){
636 boolean isOrdered = false;
637 voc = getVocabulary(uuidUserDefinedModifierVocabulary, "User defined vocabulary for modifier", "User Defined Modifier", null, null, isOrdered, modifier);
638 }
639 voc.addTerm(modifier);
640 getTermService().save(modifier);
641 }
642 state.putModifier(modifier);
643 }
644 return modifier;
645 }
646
647 /**
648 * Returns a taxon relationship type for a given uuid by first checking if the uuid has already been used in this import, if not
649 * checking if the taxon relationship type exists in the database, if not creating it anew (with vocabulary etc.).
650 * If label, text and labelAbbrev are all <code>null</code> no taxon relationship type is created.
651 * @param state
652 * @param uuid
653 * @param label
654 * @param text
655 * @param labelAbbrev
656 * @return
657 */
658 protected TaxonRelationshipType getTaxonRelationshipType(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary<TaxonRelationshipType> voc){
659 if (uuid == null){
660 return null;
661 }
662 TaxonRelationshipType relType = state.getTaxonRelationshipType(uuid);
663 if (relType == null){
664 relType = (TaxonRelationshipType)getTermService().find(uuid);
665 if (relType == null && ! hasNoLabel(label, text, labelAbbrev)){
666 relType = new TaxonRelationshipType();
667 Representation repr = Representation.NewInstance(text, label, labelAbbrev, Language.DEFAULT());
668 relType.addRepresentation(repr);
669 relType.setUuid(uuid);
670 if (voc == null){
671 boolean isOrdered = true;
672 voc = getVocabulary(uuidUserDefinedTaxonRelationshipTypeVocabulary, "User defined vocabulary for taxon relationship types", "User Defined Taxon Relationship Types", null, null, isOrdered, relType);
673 }
674 voc.addTerm(relType);
675 getTermService().save(relType);
676 }
677 state.putTaxonRelationshipType(relType);
678 }
679 return relType;
680 }
681
682 private boolean hasNoLabel(String label, String text, String labelAbbrev) {
683 return label == null && text == null && labelAbbrev == null;
684 }
685
686
687 /**
688 * Returns a presence term for a given uuid by first ...
689 * @param state
690 * @param uuid
691 * @param label
692 * @param text
693 * @param labelAbbrev
694 * @return
695 */
696 protected PresenceTerm getPresenceTerm(STATE state, UUID uuid, String label, String text, String labelAbbrev){
697 if (uuid == null){
698 return null;
699 }
700 PresenceTerm presenceTerm = state.getPresenceTerm(uuid);
701 if (presenceTerm == null){
702 presenceTerm = (PresenceTerm)getTermService().find(uuid);
703 if (presenceTerm == null){
704 presenceTerm = PresenceTerm.NewInstance(text, label, labelAbbrev);
705 presenceTerm.setUuid(uuid);
706 //set vocabulary ; FIXME use another user-defined vocabulary
707 UUID uuidPresenceVoc = UUID.fromString("adbbbe15-c4d3-47b7-80a8-c7d104e53a05");
708 TermVocabulary<PresenceTerm> voc = getVocabularyService().find(uuidPresenceVoc);
709 voc.addTerm(presenceTerm);
710 getTermService().save(presenceTerm);
711 }
712 state.putPresenceTerm(presenceTerm);
713 }
714 return presenceTerm;
715 }
716
717 /**
718 * Returns a language for a given uuid by first ...
719 * @param state
720 * @param uuid
721 * @param label
722 * @param text
723 * @param labelAbbrev
724 * @return
725 */
726 protected Language getLanguage(STATE state, UUID uuid, String label, String text, String labelAbbrev){
727 return getLanguage(state, uuid, label, text, labelAbbrev, null);
728 }
729
730 protected Language getLanguage(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary voc){
731 if (uuid == null){
732 return null;
733 }
734 Language language = state.getLanguage(uuid);
735 if (language == null){
736 language = (Language)getTermService().find(uuid);
737 if (language == null){
738 language = Language.NewInstance(text, label, labelAbbrev);
739
740 language.setUuid(uuid);
741 if (voc == null){
742 UUID uuidLanguageVoc = UUID.fromString("463a96f1-20ba-4a4c-9133-854c1682bd9b");
743 boolean isOrdered = false;
744 voc = getVocabulary(uuidLanguageVoc, "User defined languages", "User defined languages", "User defined languages", null, isOrdered, language);
745 }
746 //set vocabulary ; FIXME use another user-defined vocabulary
747
748 voc.addTerm(language);
749 getTermService().save(language);
750 }
751 state.putLanguage(language);
752 }
753 return language;
754 }
755
756
757 /**
758 * @param uuid
759 * @return
760 *
761 */
762 protected <T extends DefinedTermBase> TermVocabulary<T> getVocabulary(UUID uuid, String text, String label, String abbrev, URI termSourceUri, boolean isOrdered, T type) {
763 List<String> propPath = Arrays.asList(new String[]{"terms"});
764 TermVocabulary<T> voc = getVocabularyService().load(uuid, propPath);
765 if (voc == null){
766 if (isOrdered){
767 voc = OrderedTermVocabulary.NewInstance(text, label, abbrev, termSourceUri);
768 }else{
769 voc = TermVocabulary.NewInstance(text, label, abbrev, termSourceUri);
770 }
771 voc.setUuid(uuid);
772 getVocabularyService().save(voc);
773 }
774 return voc;
775 }
776
777 /**
778 * Adds an orginal source to a sourceable objects (implemented for Identifiable entity and description element.
779 * If cdmBase is not sourceable nothing happens.
780 * TODO Move to DbImportBase once this exists.
781 * TODO also implemented in DbImportObjectCreationMapper (reduce redundance)
782 * @param rs
783 * @param cdmBase
784 * @param dbIdAttribute
785 * @param namespace
786 * @param citation
787 * @throws SQLException
788 */
789 public void addOriginalSource(CdmBase cdmBase, Object idAttributeValue, String namespace, Reference citation) {
790 if (cdmBase instanceof ISourceable ){
791 IOriginalSource source;
792 ISourceable sourceable = (ISourceable<?>)cdmBase;
793 Object id = idAttributeValue;
794 String strId = String.valueOf(id);
795 String microCitation = null;
796 OriginalSourceType type = OriginalSourceType.Import;
797 if (cdmBase instanceof IdentifiableEntity){
798 source = IdentifiableSource.NewInstance(type, strId, namespace, citation, microCitation);
799 }else if (cdmBase instanceof DescriptionElementBase){
800 source = DescriptionElementSource.NewInstance(type, strId, namespace, citation, microCitation);
801 }else{
802 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.");
803 return;
804 }
805 sourceable.addSource(source);
806 }else if (cdmBase != null){
807 logger.warn("Sourced object does not implement ISourceable: " + cdmBase.getClass() + "," + cdmBase.getUuid());
808 }else{
809 logger.warn("Sourced object is null");
810 }
811 }
812
813 /**
814 * @see #addOriginalSource(CdmBase, Object, String, Reference)
815 * @param rs
816 * @param cdmBase
817 * @param dbIdAttribute
818 * @param namespace
819 * @param citation
820 * @throws SQLException
821 */
822 public void addOriginalSource(ResultSet rs, CdmBase cdmBase, String dbIdAttribute, String namespace, Reference citation) throws SQLException {
823 Object id = rs.getObject(dbIdAttribute);
824 addOriginalSource(cdmBase, id, namespace, citation);
825 }
826
827
828 /**
829 * If the child taxon is missing genus or species epithet information and the rank is below <i>genus</i>
830 * or <i>species</i> respectively the according epithets are taken from the parent taxon.
831 * If the name is an autonym and has no combination author/basionym author the authors are taken from
832 * the parent.
833 * @param parentTaxon
834 * @param childTaxon
835 */
836 protected void fillMissingEpithetsForTaxa(Taxon parentTaxon, Taxon childTaxon) {
837 NonViralName parentName = HibernateProxyHelper.deproxy(parentTaxon.getName(), NonViralName.class);
838 NonViralName childName = HibernateProxyHelper.deproxy(childTaxon.getName(), NonViralName.class);
839 fillMissingEpithets(parentName, childName);
840 }
841
842 /**
843 * If the child name is missing genus or species epithet information and the rank is below <i>genus</i>
844 * or <i>species</i> respectively the according epithets are taken from the parent name.
845 * If the name is an autonym and has no combination author/basionym author the authors are taken from
846 * the parent.
847 * @param parentTaxon
848 * @param childTaxon
849 */
850 protected void fillMissingEpithets(NonViralName parentName, NonViralName childName) {
851 if (StringUtils.isBlank(childName.getGenusOrUninomial()) && childName.getRank().isLower(Rank.GENUS()) ){
852 childName.setGenusOrUninomial(parentName.getGenusOrUninomial());
853 }
854
855 if (StringUtils.isBlank(childName.getSpecificEpithet()) && childName.getRank().isLower(Rank.SPECIES()) ){
856 childName.setSpecificEpithet(parentName.getSpecificEpithet());
857 }
858 if (childName.isAutonym() && childName.getCombinationAuthorTeam() == null && childName.getBasionymAuthorTeam() == null ){
859 childName.setCombinationAuthorTeam(parentName.getCombinationAuthorTeam());
860 childName.setBasionymAuthorTeam(parentName.getBasionymAuthorTeam());
861 }
862 }
863
864 /**
865 * Returns the taxon description for a taxon. If there are multiple taxon descriptions
866 * an arbitrary one is chosen.
867 * If no taxon description exists, a new one is created if <code>createNewIfNotExists</code>
868 * is <code>true</code>.
869 * @param createNewIfNotExists
870 * @param isImageGallery if true only taxon description being image galleries are considered.
871 * If false only taxon description being no image galleries are considered.
872 * @return
873 */
874 public TaxonNameDescription getTaxonNameDescription(TaxonNameBase name, boolean isImageGallery, boolean createNewIfNotExists) {
875 Reference<?> ref = null;
876 return getTaxonNameDescription(name, ref, isImageGallery, createNewIfNotExists);
877 }
878
879 /**
880 * Like {@link #getTaxonDescription(Taxon, boolean, boolean)}
881 * Only matches a description if the given reference is a source of the description.<BR>
882 * If a new description is created the given reference will be added as a source.
883 *
884 * @see #getTaxonDescription(Taxon, boolean, boolean)
885 */
886 public TaxonNameDescription getTaxonNameDescription(TaxonNameBase<?,?> name, Reference ref, boolean isImageGallery, boolean createNewIfNotExists) {
887 TaxonNameDescription result = null;
888 Set<TaxonNameDescription> descriptions= name.getDescriptions();
889 for (TaxonNameDescription description : descriptions){
890 if (description.isImageGallery() == isImageGallery){
891 if (hasCorrespondingSource(ref, description)){
892 result = description;
893 break;
894 }
895 }
896 }
897 if (result == null && createNewIfNotExists){
898 result = TaxonNameDescription.NewInstance(name);
899 result.setImageGallery(isImageGallery);
900 if (ref != null){
901 result.addImportSource(null, null, ref, null);
902 }
903 }
904 return result;
905 }
906
907 /**
908 * Returns the taxon description for a taxon. If there are multiple taxon descriptions
909 * an arbitrary one is chosen.
910 * If no taxon description exists, a new one is created if <code>createNewIfNotExists</code>
911 * is <code>true</code>.
912 * @param createNewIfNotExists
913 * @param isImageGallery if true only taxon description being image galleries are considered.
914 * If false only taxon description being no image galleries are considered.
915 * @return
916 */
917 public TaxonDescription getTaxonDescription(Taxon taxon, boolean isImageGallery, boolean createNewIfNotExists) {
918 Reference<?> ref = null;
919 return getTaxonDescription(taxon, ref, isImageGallery, createNewIfNotExists);
920 }
921
922 /**
923 * Like {@link #getTaxonDescription(Taxon, boolean, boolean)}
924 * Only matches a description if the given reference is a source of the description.<BR>
925 * If a new description is created the given reference will be added as a source.
926 *
927 * @see #getTaxonDescription(Taxon, boolean, boolean)
928 */
929 public TaxonDescription getTaxonDescription(Taxon taxon, Reference ref, boolean isImageGallery, boolean createNewIfNotExists) {
930 TaxonDescription result = null;
931 Set<TaxonDescription> descriptions= taxon.getDescriptions();
932 for (TaxonDescription description : descriptions){
933 if (description.isImageGallery() == isImageGallery){
934 if (hasCorrespondingSource(ref, description)){
935 result = description;
936 break;
937 }
938 }
939 }
940 if (result == null && createNewIfNotExists){
941 result = TaxonDescription.NewInstance(taxon);
942 result.setImageGallery(isImageGallery);
943 if (ref != null){
944 result.addImportSource(null, null, ref, null);
945 }
946 }
947 return result;
948 }
949
950
951 /**
952 * Returns the {@link SpecimenDescription specimen description} for a {@link SpecimenOrObservationBase specimen or observation}.
953 * If there are multiple specimen descriptions an arbitrary one is chosen.
954 * If no specimen description exists, a new one is created if <code>createNewIfNotExists</code> is <code>true</code>.
955 * @param createNewIfNotExists
956 * @param isImageGallery if true only specimen description being image galleries are considered.
957 * If false only specimen description being no image galleries are considered.
958 * @return
959 */
960 public SpecimenDescription getSpecimenDescription(SpecimenOrObservationBase specimen, boolean isImageGallery, boolean createNewIfNotExists) {
961 Reference ref = null;
962 return getSpecimenDescription(specimen, ref, isImageGallery, createNewIfNotExists);
963 }
964
965 /**
966 * Like {@link #getSpecimenDescription(SpecimenOrObservationBase, boolean, boolean)}
967 * Only matches a description if the given reference is a source of the description.<BR>
968 * If a new description is created the given reference will be added as a source.
969 *
970 * @see #getTaxonDescription(Taxon, boolean, boolean)
971 */
972 public SpecimenDescription getSpecimenDescription(SpecimenOrObservationBase specimen, Reference ref, boolean isImageGallery, boolean createNewIfNotExists) {
973 SpecimenDescription result = null;
974 Set<SpecimenDescription> descriptions= specimen.getDescriptions();
975 for (SpecimenDescription description : descriptions){
976 if (description.isImageGallery() == isImageGallery){
977 if (hasCorrespondingSource(ref, description)){
978 result = description;
979 break;
980 }
981 }
982 }
983 if (result == null && createNewIfNotExists){
984 result = SpecimenDescription.NewInstance(specimen);
985 result.setImageGallery(isImageGallery);
986 if (ref != null){
987 result.addImportSource(null, null, ref, null);
988 }
989 }
990 return result;
991 }
992
993
994 /**
995 * Returns the textdata that holds general information about a feature for a taxon description.
996 * This is mainly necessary for descriptions that have more than one description element for
997 * a given feature such as 'distribution', 'description' or 'common name'. It may also hold
998 * for hierarchical features where no description element exists for a higher hierarchy level.
999 * Example: the description feature has subfeatures. But some information like authorship, figures,
1000 * sources need to be added to the description itself.
1001 * Currently a feature placeholder is marked by a marker of type 'feature placeholder'. Maybe in future
1002 * there will be a boolean marker in the TextData class itself.
1003 * @param state
1004 * @param feature
1005 * @param taxon
1006 * @param ref
1007 * @param createIfNotExists
1008 * @return
1009 */
1010 protected TextData getFeaturePlaceholder(STATE state, DescriptionBase<?> description, Feature feature, boolean createIfNotExists) {
1011 UUID featurePlaceholderUuid = MarkupTransformer.uuidFeaturePlaceholder;
1012 for (DescriptionElementBase element : description.getElements()){
1013 if (element.isInstanceOf(TextData.class)){
1014 TextData textData = CdmBase.deproxy(element, TextData.class);
1015 if (textData.getFeature() == null || ! textData.getFeature().equals(feature)){
1016 continue;
1017 }
1018 for (Marker marker : textData.getMarkers()){
1019 MarkerType markerType = marker.getMarkerType();
1020 if (markerType != null &&
1021 markerType.getUuid().equals(featurePlaceholderUuid) &&
1022 marker.getValue() == true){
1023 return textData;
1024 }
1025 }
1026 }
1027 }
1028 if (createIfNotExists){
1029 TextData newPlaceholder = TextData.NewInstance(feature);
1030 MarkerType placeholderMarkerType = getMarkerType(state, featurePlaceholderUuid, "Feature Placeholder", "Feature Placeholder", null);
1031 Marker marker = Marker.NewInstance(placeholderMarkerType, true);
1032 newPlaceholder.addMarker(marker);
1033 description.addElement(newPlaceholder);
1034 return newPlaceholder;
1035 }else{
1036 return null;
1037 }
1038 }
1039
1040
1041
1042 /**
1043 * Returns true, if this description has a source with a citation equal to the given reference.
1044 * Returns true if the given reference is null.
1045 * @param ref
1046 * @param description
1047 */
1048 private boolean hasCorrespondingSource(Reference<?> ref, DescriptionBase<?> description) {
1049 if (ref != null){
1050 for (IdentifiableSource source : description.getSources()){
1051 if (ref.equals(source.getCitation())){
1052 return true;
1053 }
1054 }
1055 return false;
1056 }
1057 return true;
1058
1059 }
1060
1061
1062 /**
1063 * Returns the accepted taxon of a {@link TaxonBase taxon base}. <BR>
1064 * If taxonBase is of type taxon the same object is returned. If taxonBase is of type
1065 * synonym the accepted taxon is returned if one exists. If no accepted taxon exists
1066 * <code>null</code> is returned. If multiple accepted taxa exist the one taxon with the
1067 * same secundum reference is returned. If no such single taxon exists an
1068 * {@link IllegalStateException illegal state exception} is thrown.
1069 * @param taxonBase
1070 * @return
1071 */
1072 protected Taxon getAcceptedTaxon(TaxonBase<?> taxonBase) {
1073 if (taxonBase == null){
1074 return null;
1075 }else if(taxonBase.isInstanceOf(Taxon.class)){
1076 return CdmBase.deproxy(taxonBase, Taxon.class);
1077 }else if(taxonBase.isInstanceOf(Synonym.class)){
1078 Synonym synonym = CdmBase.deproxy(taxonBase, Synonym.class);
1079 Set<Taxon> acceptedTaxa = synonym.getAcceptedTaxa();
1080 if (acceptedTaxa.size() == 0){
1081 return null;
1082 }else if (acceptedTaxa.size() == 1){
1083 return acceptedTaxa.iterator().next();
1084 }else{
1085 Reference<?> sec = synonym.getSec();
1086 if (sec != null){
1087 Set<Taxon> taxaWithSameSec = new HashSet<Taxon>();
1088 for (Taxon taxon: acceptedTaxa){
1089 if (sec.equals(taxon.getSec())){
1090 taxaWithSameSec.add(taxon);
1091 }
1092 }
1093 if (taxaWithSameSec.size() == 1){
1094 return taxaWithSameSec.iterator().next();
1095 }
1096 }
1097 throw new IllegalStateException("Can't define the one accepted taxon for a synonym out of multiple accept taxa");
1098 }
1099 }else{
1100 throw new IllegalStateException("Unknown TaxonBase subclass: " + taxonBase.getClass().getName());
1101 }
1102 }
1103
1104
1105
1106 /**
1107 * Creates
1108 * @param uriString
1109 * @param readDataFromUrl
1110 * @see #READ_MEDIA_DATA
1111 * @return
1112 * @throws MalformedURLException
1113 */
1114 protected Media getImageMedia(String uriString, boolean readMediaData, boolean isFigure) throws MalformedURLException {
1115 if( uriString == null){
1116 return null;
1117 } else {
1118 ImageInfo imageInfo = null;
1119 URI uri;
1120 uriString = uriString.replace(" ", "%20"); //replace whitespace
1121 try {
1122 uri = new URI(uriString);
1123 try {
1124 if (readMediaData){
1125 imageInfo = ImageInfo.NewInstance(uri, 0);
1126 }
1127 } catch (Exception e) {
1128 String message = "An error occurred when trying to read image meta data for " + uri.toString() + ": " + e.getMessage();
1129 logger.warn(message);
1130 fireWarningEvent(message, "unknown location", 2, 0);
1131 }
1132 ImageFile imageFile = ImageFile.NewInstance(uri, null, imageInfo);
1133 MediaRepresentation representation = MediaRepresentation.NewInstance();
1134 if(imageInfo != null){
1135 representation.setMimeType(imageInfo.getMimeType());
1136 representation.setSuffix(imageInfo.getSuffix());
1137 }
1138 representation.addRepresentationPart(imageFile);
1139 Media media = isFigure ? Figure.NewInstance() : Media.NewInstance();
1140 media.addRepresentation(representation);
1141 return media;
1142 } catch (URISyntaxException e1) {
1143 String message = "An URISyntaxException occurred when trying to create uri from multimedia objcet string: " + uriString;
1144 logger.warn(message);
1145 fireWarningEvent(message, "unknown location", 4, 0);
1146 return null;
1147 }
1148 }
1149 }
1150
1151
1152 /**
1153 * Retrieves an Integer value from a result set. If the value is NULL null is returned.
1154 * ResultSet.getInt() returns 0 therefore we need a special handling for this case.
1155 * @param rs
1156 * @param columnName
1157 * @return
1158 * @throws SQLException
1159 */
1160 protected Integer nullSafeInt(ResultSet rs, String columnName) throws SQLException {
1161 Object intObject = rs.getObject(columnName);
1162 if (intObject == null){
1163 return null;
1164 }else{
1165 return Integer.valueOf(intObject.toString());
1166 }
1167 }
1168
1169 protected Double nullSafeDouble(ResultSet rs, String columnName) throws SQLException {
1170 Object doubleObject = rs.getObject(columnName);
1171 if (doubleObject == null){
1172 return null;
1173 }else{
1174 return Double.valueOf(doubleObject.toString());
1175 }
1176 }
1177
1178 protected Float nullSafeFloat(ResultSet rs, String columnName) throws SQLException {
1179 Object doubleObject = rs.getObject(columnName);
1180 if (doubleObject == null){
1181 return null;
1182 }else{
1183 return Float.valueOf(doubleObject.toString());
1184 }
1185 }
1186
1187
1188 /**
1189 * Returns <code>null</code> for all blank strings. Identity function otherwise.
1190 * @param str
1191 * @return
1192 */
1193 protected String NB(String str) {
1194 if (StringUtils.isBlank(str)){
1195 return null;
1196 }else{
1197 return str;
1198 }
1199 }
1200
1201
1202 }