Refactored MediaMetaData and family. Renamed it to MediaInfo. API is now less confusi...
[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.HashSet;
18 import java.util.List;
19 import java.util.Set;
20 import java.util.UUID;
21
22 import org.apache.log4j.Logger;
23
24 import eu.etaxonomy.cdm.api.service.pager.Pager;
25 import eu.etaxonomy.cdm.common.CdmUtils;
26 import eu.etaxonomy.cdm.common.media.ImageInfo;
27 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
28 import eu.etaxonomy.cdm.io.common.mapping.IInputTransformer;
29 import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
30 import eu.etaxonomy.cdm.model.common.AnnotationType;
31 import eu.etaxonomy.cdm.model.common.CdmBase;
32 import eu.etaxonomy.cdm.model.common.DescriptionElementSource;
33 import eu.etaxonomy.cdm.model.common.ExtensionType;
34 import eu.etaxonomy.cdm.model.common.IOriginalSource;
35 import eu.etaxonomy.cdm.model.common.ISourceable;
36 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
37 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
38 import eu.etaxonomy.cdm.model.common.Language;
39 import eu.etaxonomy.cdm.model.common.MarkerType;
40 import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
41 import eu.etaxonomy.cdm.model.common.TermVocabulary;
42 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
43 import eu.etaxonomy.cdm.model.description.Feature;
44 import eu.etaxonomy.cdm.model.description.PresenceTerm;
45 import eu.etaxonomy.cdm.model.description.TaxonDescription;
46 import eu.etaxonomy.cdm.model.location.NamedArea;
47 import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
48 import eu.etaxonomy.cdm.model.location.NamedAreaType;
49 import eu.etaxonomy.cdm.model.location.ReferenceSystem;
50 import eu.etaxonomy.cdm.model.media.ImageFile;
51 import eu.etaxonomy.cdm.model.media.Media;
52 import eu.etaxonomy.cdm.model.media.MediaRepresentation;
53 import eu.etaxonomy.cdm.model.name.NonViralName;
54 import eu.etaxonomy.cdm.model.name.Rank;
55 import eu.etaxonomy.cdm.model.reference.Reference;
56 import eu.etaxonomy.cdm.model.taxon.Classification;
57 import eu.etaxonomy.cdm.model.taxon.Synonym;
58 import eu.etaxonomy.cdm.model.taxon.Taxon;
59 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
60
61 /**
62 * @author a.mueller
63 * @created 01.07.2008
64 * @version 1.0
65 */
66 public abstract class CdmImportBase<CONFIG extends IImportConfigurator, STATE extends ImportStateBase> extends CdmIoBase<STATE> implements ICdmImport<CONFIG, STATE>{
67 private static Logger logger = Logger.getLogger(CdmImportBase.class);
68
69 protected static final boolean CREATE = true;
70 protected static final boolean IMAGE_GALLERY = true;
71
72 public static final UUID uuidUserDefinedNamedAreaLevelVocabulary = UUID.fromString("255144da-8d95-457e-a327-9752a8f85e5a");
73 public static final UUID uuidUserDefinedNamedAreaVocabulary = UUID.fromString("b2238399-a3af-4f6d-b7eb-ff5d0899bf1b");
74 public static final UUID uuidUserDefinedExtensionTypeVocabulary = UUID.fromString("e28c1394-1be8-4847-8b81-ab44eb6d5bc8");
75 public static final UUID uuidUserDefinedReferenceSystemVocabulary = UUID.fromString("467591a3-10b4-4bf1-9239-f06ece33e90a");
76
77 private static final String UuidOnly = "UUIDOnly";
78 private static final String UuidLabel = "UUID or label";
79 private static final String UuidLabelAbbrev = "UUID, label or abbreviation";
80 private static final String UuidAbbrev = "UUID or abbreviation";
81
82 public enum TermMatchMode{
83 UUID_ONLY(0, UuidOnly)
84 ,UUID_LABEL(1, UuidLabel)
85 ,UUID_LABEL_ABBREVLABEL(2, UuidLabelAbbrev)
86 ,UUID_ABBREVLABEL(3, UuidAbbrev)
87 ;
88
89
90 private int id;
91 private String representation;
92 private TermMatchMode(int id, String representation){
93 this.id = id;
94 this.representation = representation;
95 }
96 public int getId() {
97 return id;
98 }
99 public String getRepresentation() {
100 return representation;
101 }
102 public TermMatchMode valueOf(int id){
103 switch (id){
104 case 0: return UUID_ONLY;
105 case 1: return UUID_LABEL;
106 case 2: return UUID_LABEL_ABBREVLABEL;
107 case 3: return UUID_ABBREVLABEL;
108 default: return UUID_ONLY;
109 }
110 }
111
112
113 }
114
115 protected Classification makeTree(STATE state, Reference reference){
116 Reference ref = CdmBase.deproxy(reference, Reference.class);
117 String treeName = "Classification (Import)";
118 if (ref != null && CdmUtils.isNotEmpty(ref.getTitleCache())){
119 treeName = ref.getTitleCache();
120 }
121 Classification tree = Classification.NewInstance(treeName);
122 tree.setReference(ref);
123
124
125 // use defined uuid for first tree
126 CONFIG config = (CONFIG)state.getConfig();
127 if (state.countTrees() < 1 ){
128 tree.setUuid(config.getClassificationUuid());
129 }
130 getClassificationService().save(tree);
131 state.putTree(ref, tree);
132 return tree;
133 }
134
135
136 /**
137 * Alternative memory saving method variant of
138 * {@link #makeTree(STATE state, Reference ref)} which stores only the
139 * UUID instead of the full tree in the <code>ImportStateBase</code> by
140 * using <code>state.putTreeUuid(ref, tree);</code>
141 *
142 * @param state
143 * @param ref
144 * @return
145 */
146 protected Classification makeTreeMemSave(STATE state, Reference ref){
147 String treeName = "Classification (Import)";
148 if (ref != null && CdmUtils.isNotEmpty(ref.getTitleCache())){
149 treeName = ref.getTitleCache();
150 }
151 Classification tree = Classification.NewInstance(treeName);
152 tree.setReference(ref);
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.putTreeUuid(ref, tree);
162 return tree;
163 }
164
165
166 protected ExtensionType getExtensionType(STATE state, UUID uuid, String label, String text, String labelAbbrev){
167 return getExtensionType(state, uuid, label, text, labelAbbrev, null);
168 }
169 protected ExtensionType getExtensionType(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary voc){
170 if (uuid == null){
171 uuid = UUID.randomUUID();
172 }
173 ExtensionType extensionType = state.getExtensionType(uuid);
174 if (extensionType == null){
175 extensionType = (ExtensionType)getTermService().find(uuid);
176 if (extensionType == null){
177 extensionType = ExtensionType.NewInstance(text, label, labelAbbrev);
178 extensionType.setUuid(uuid);
179 if (voc == null){
180 boolean isOrdered = false;
181 voc = getVocabulary(uuidUserDefinedExtensionTypeVocabulary, "User defined vocabulary for extension types", "User Defined Extension Types", null, null, isOrdered);
182 }
183 voc.addTerm(extensionType);
184 getTermService().save(extensionType);
185 }
186 state.putExtensionType(extensionType);
187 }
188 return extensionType;
189 }
190
191
192 protected MarkerType getMarkerType(STATE state, String keyString) {
193 IInputTransformer transformer = state.getTransformer();
194 MarkerType markerType = null;
195 try {
196 markerType = transformer.getMarkerTypeByKey(keyString);
197 } catch (UndefinedTransformerMethodException e) {
198 logger.info("getMarkerTypeByKey not yet implemented for this import");
199 }
200 if (markerType == null ){
201 UUID uuid;
202 try {
203 uuid = transformer.getMarkerTypeUuid(keyString);
204 return getMarkerType(state, uuid, keyString, keyString, keyString);
205 } catch (UndefinedTransformerMethodException e) {
206 logger.warn("getMarkerTypeUuid not yet implemented for this import");
207 }
208 }
209 return null;
210 }
211
212 protected MarkerType getMarkerType(STATE state, UUID uuid, String label, String text, String labelAbbrev){
213 if (uuid == null){
214 uuid = UUID.randomUUID();
215 }
216 MarkerType markerType = state.getMarkerType(uuid);
217 if (markerType == null){
218 markerType = (MarkerType)getTermService().find(uuid);
219 if (markerType == null){
220 markerType = MarkerType.NewInstance(label, text, labelAbbrev);
221 markerType.setUuid(uuid);
222 UUID uuidMarkerTypeVoc = UUID.fromString("19dffff7-e142-429c-a420-5d28e4ebe305");
223 TermVocabulary voc = getVocabularyService().find(uuidMarkerTypeVoc);
224 voc.addTerm(markerType);
225 getTermService().save(markerType);
226 }
227 state.putMarkerType(markerType);
228 }
229 return markerType;
230 }
231
232 protected AnnotationType getAnnotationType(STATE state, UUID uuid, String label, String text, String labelAbbrev){
233 if (uuid == null){
234 uuid = UUID.randomUUID();
235 }
236 AnnotationType annotationType = state.getAnnotationType(uuid);
237 if (annotationType == null){
238 annotationType = (AnnotationType)getTermService().find(uuid);
239 if (annotationType == null){
240 annotationType = AnnotationType.NewInstance(label, text, labelAbbrev);
241 annotationType.setUuid(uuid);
242 UUID uuidAnnotationTypeVoc = UUID.fromString("ca04609b-1ba0-4d31-9c2e-aa8eb2f4e62d");
243 TermVocabulary voc = getVocabularyService().find(uuidAnnotationTypeVoc);
244 voc.addTerm(annotationType);
245 getTermService().save(annotationType);
246 }
247 state.putAnnotationType(annotationType);
248 }
249 return annotationType;
250 }
251
252
253 protected ReferenceSystem getReferenceSystem(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary voc){
254 if (uuid == null){
255 uuid = UUID.randomUUID();
256 }
257 ReferenceSystem refSystem = state.getReferenceSystem(uuid);
258 if (refSystem == null){
259 refSystem = (ReferenceSystem)getTermService().find(uuid);
260 if (refSystem == null){
261 refSystem = ReferenceSystem.NewInstance(text, label, labelAbbrev);
262 if (voc == null){
263 boolean isOrdered = false;
264 voc = getVocabulary(uuidUserDefinedReferenceSystemVocabulary, "User defined vocabulary for named areas", "User Defined Reference System", null, null, isOrdered);
265 }
266 voc.addTerm(refSystem);
267 refSystem.setUuid(uuid);
268 getTermService().save(refSystem);
269 }
270 state.putReferenceSystem(refSystem);
271 }
272 return refSystem;
273
274 }
275
276 /**
277 * Returns a named area for a given uuid by first . If the named area does not
278 * @param state
279 * @param uuid
280 * @param label
281 * @param text
282 * @param labelAbbrev
283 * @param areaType
284 * @param level
285 * @return
286 */
287 protected NamedArea getNamedArea(STATE state, UUID uuid, String label, String text, String labelAbbrev, NamedAreaType areaType, NamedAreaLevel level){
288 return getNamedArea(state, uuid, label, text, labelAbbrev, areaType, level, null, null);
289 }
290
291 protected NamedArea getNamedArea(STATE state, UUID uuid, String label, String text, String labelAbbrev, NamedAreaType areaType, NamedAreaLevel level, TermVocabulary voc, TermMatchMode matchMode){
292 if (uuid == null){
293 uuid = UUID.randomUUID();
294 }
295 if (matchMode == null){
296 matchMode = TermMatchMode.UUID_ONLY;
297 }
298 NamedArea namedArea = state.getNamedArea(uuid);
299 if (namedArea == null){
300 //TODO matching still experimental
301 namedArea = (NamedArea)getTermService().find(uuid);
302 if (namedArea == null && matchMode.equals(TermMatchMode.UUID_LABEL)){
303 logger.warn("UUID_LABEL not yet implemented");
304 }
305 if (namedArea == null && matchMode.equals(TermMatchMode.UUID_ABBREVLABEL)){
306 Pager<NamedArea> areaPager = getTermService().findByRepresentationAbbreviation(labelAbbrev, NamedArea.class, null, null);
307 namedArea = findBestMatchingArea(areaPager, uuid, label, text, labelAbbrev, areaType, level, voc);
308 }
309 if (namedArea == null && matchMode.equals(TermMatchMode.UUID_LABEL_ABBREVLABEL)){
310 logger.warn("UUID_LABEL not yet implemented");
311 }
312
313 if (namedArea == null){
314 namedArea = NamedArea.NewInstance(text, label, labelAbbrev);
315 if (voc == null){
316 boolean isOrdered = true;
317 voc = getVocabulary(uuidUserDefinedNamedAreaVocabulary, "User defined vocabulary for named areas", "User Defined Named Areas", null, null, isOrdered);
318 }
319 voc.addTerm(namedArea);
320 namedArea.setType(areaType);
321 namedArea.setLevel(level);
322 namedArea.setUuid(uuid);
323 getTermService().save(namedArea);
324 }
325 state.putNamedArea(namedArea);
326 }
327 return namedArea;
328 }
329
330
331 private NamedArea findBestMatchingArea(Pager<NamedArea> areaPager, UUID uuid, String label, String text, String abbrev,
332 NamedAreaType areaType, NamedAreaLevel level, TermVocabulary voc) {
333 // TODO preliminary implementation
334 List<NamedArea> list = areaPager.getRecords();
335 if (list.size() == 0){
336 return null;
337 }else if (list.size() == 1){
338 return list.get(0);
339 }else if (list.size() > 1){
340 String message = "There is more than 1 matching area for %s, %s, %s. As a preliminary implementation I take the first";
341 message = String.format(message, label, abbrev, text);
342 logger.warn(message);
343 return list.get(0);
344 }
345 return null;
346 }
347
348
349 protected NamedAreaLevel getNamedAreaLevel(STATE state, UUID uuid, String label, String text, String labelAbbrev, TermVocabulary<NamedAreaLevel> voc){
350 if (uuid == null){
351 uuid = UUID.randomUUID();
352 }
353 NamedAreaLevel namedAreaLevel = state.getNamedAreaLevel(uuid);
354 if (namedAreaLevel == null){
355 namedAreaLevel = CdmBase.deproxy(getTermService().find(uuid), NamedAreaLevel.class);
356 if (namedAreaLevel == null){
357 namedAreaLevel = NamedAreaLevel.NewInstance(text, label, labelAbbrev);
358 if (voc == null){
359 boolean isOrdered = true;
360 voc = getVocabulary(uuidUserDefinedNamedAreaLevelVocabulary, "User defined vocabulary for named area levels", "User Defined Named Area Levels", null, null, isOrdered);
361 }
362 voc.addTerm(namedAreaLevel);
363 namedAreaLevel.setUuid(uuid);
364 getTermService().save(namedAreaLevel);
365 }
366 state.putNamedAreaLevel(namedAreaLevel);
367 }
368 return namedAreaLevel;
369 }
370
371 /**
372 * Returns a feature for a given uuid by first ...
373 * @param state
374 * @param uuid
375 * @param label
376 * @param text
377 * @param labelAbbrev
378 * @return
379 */
380 protected Feature getFeature(STATE state, UUID uuid, String label, String text, String labelAbbrev){
381 if (uuid == null){
382 return null;
383 }
384 Feature feature = state.getFeature(uuid);
385 if (feature == null){
386 feature = (Feature)getTermService().find(uuid);
387 if (feature == null){
388 feature = Feature.NewInstance(text, label, labelAbbrev);
389 feature.setUuid(uuid);
390 feature.setSupportsTextData(true);
391 //set vocabulary ; FIXME use another user-defined vocabulary
392 UUID uuidFeatureVoc = UUID.fromString("b187d555-f06f-4d65-9e53-da7c93f8eaa8");
393 TermVocabulary<Feature> voc = getVocabularyService().find(uuidFeatureVoc);
394 voc.addTerm(feature);
395 getTermService().save(feature);
396 }
397 state.putFeature(feature);
398 }
399 return feature;
400 }
401
402 /**
403 * Returns a presence term for a given uuid by first ...
404 * @param state
405 * @param uuid
406 * @param label
407 * @param text
408 * @param labelAbbrev
409 * @return
410 */
411 protected PresenceTerm getPresenceTerm(STATE state, UUID uuid, String label, String text, String labelAbbrev){
412 if (uuid == null){
413 return null;
414 }
415 PresenceTerm presenceTerm = state.getPresenceTerm(uuid);
416 if (presenceTerm == null){
417 presenceTerm = (PresenceTerm)getTermService().find(uuid);
418 if (presenceTerm == null){
419 presenceTerm = PresenceTerm.NewInstance(text, label, labelAbbrev);
420 presenceTerm.setUuid(uuid);
421 //set vocabulary ; FIXME use another user-defined vocabulary
422 UUID uuidPresenceVoc = UUID.fromString("adbbbe15-c4d3-47b7-80a8-c7d104e53a05");
423 TermVocabulary<PresenceTerm> voc = getVocabularyService().find(uuidPresenceVoc);
424 voc.addTerm(presenceTerm);
425 getTermService().save(presenceTerm);
426 }
427 state.putPresenceTerm(presenceTerm);
428 }
429 return presenceTerm;
430 }
431
432 /**
433 * Returns a language for a given uuid by first ...
434 * @param state
435 * @param uuid
436 * @param label
437 * @param text
438 * @param labelAbbrev
439 * @return
440 */
441 protected Language getLanguage(STATE state, UUID uuid, String label, String text, String labelAbbrev){
442 if (uuid == null){
443 return null;
444 }
445 Language language = state.getLanguage(uuid);
446 if (language == null){
447 language = (Language)getTermService().find(uuid);
448 if (language == null){
449 language = Language.NewInstance(text, label, labelAbbrev);
450
451 language.setUuid(uuid);
452 //set vocabulary ; FIXME use another user-defined vocabulary
453 UUID uuidLanguageVoc = UUID.fromString("45ac7043-7f5e-4f37-92f2-3874aaaef2de");
454 TermVocabulary<Language> voc = getVocabularyService().find(uuidLanguageVoc);
455 voc.addTerm(language);
456 getTermService().save(language);
457 }
458 state.putLanguage(language);
459 }
460 return language;
461 }
462
463
464 /**
465 * @param uuid
466 * @return
467 *
468 */
469 protected TermVocabulary getVocabulary(UUID uuid, String text, String label, String abbrev, URI termSourceUri, boolean isOrdered) {
470 TermVocabulary voc = getVocabularyService().find(uuid);
471 if (voc == null){
472 if (isOrdered){
473 voc = OrderedTermVocabulary.NewInstance(text, label, abbrev, termSourceUri);
474 }else{
475 voc = TermVocabulary.NewInstance(text, label, abbrev, termSourceUri);
476 }
477 voc.setUuid(uuid);
478 getVocabularyService().save(voc);
479 }
480 return voc;
481 }
482
483 /**
484 * Adds an orginal source to a sourceable objects (implemented for Identifiable entity and description element.
485 * If cdmBase is not sourceable nothing happens.
486 * TODO Move to DbImportBase once this exists.
487 * TODO also implemented in DbImportObjectCreationMapper (reduce redundance)
488 * @param rs
489 * @param cdmBase
490 * @param dbIdAttribute
491 * @param namespace
492 * @param citation
493 * @throws SQLException
494 */
495 public void addOriginalSource(CdmBase cdmBase, Object idAttributeValue, String namespace, Reference citation) {
496 if (cdmBase instanceof ISourceable ){
497 IOriginalSource source;
498 ISourceable sourceable = (ISourceable)cdmBase;
499 Object id = idAttributeValue;
500 String strId = String.valueOf(id);
501 String microCitation = null;
502 if (cdmBase instanceof IdentifiableEntity){
503 source = IdentifiableSource.NewInstance(strId, namespace, citation, microCitation);
504 }else if (cdmBase instanceof DescriptionElementBase){
505 source = DescriptionElementSource.NewInstance(strId, namespace, citation, microCitation);
506 }else{
507 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.");
508 return;
509 }
510 sourceable.addSource(source);
511 }else if (cdmBase != null){
512 logger.warn("Sourced object does not implement ISourceable: " + cdmBase.getClass() + "," + cdmBase.getUuid());
513 }else{
514 logger.warn("Sourced object is null");
515 }
516 }
517
518 /**
519 * @see #addOriginalSource(CdmBase, Object, String, Reference)
520 * @param rs
521 * @param cdmBase
522 * @param dbIdAttribute
523 * @param namespace
524 * @param citation
525 * @throws SQLException
526 */
527 public void addOriginalSource(ResultSet rs, CdmBase cdmBase, String dbIdAttribute, String namespace, Reference citation) throws SQLException {
528 Object id = rs.getObject(dbIdAttribute);
529 addOriginalSource(cdmBase, id, namespace, citation);
530 }
531
532
533 /**
534 * If the child taxon is missing genus or species epithet information and the rank is below <i>genus</i>
535 * or <i>species</i> respectively the according epithets are taken from the parent taxon.
536 * If the name is an autonym and has no combination author/basionym author the authors are taken from
537 * the parent.
538 * @param parentTaxon
539 * @param childTaxon
540 */
541 protected void fillMissingEpithetsForTaxa(Taxon parentTaxon, Taxon childTaxon) {
542 NonViralName parentName = HibernateProxyHelper.deproxy(parentTaxon.getName(), NonViralName.class);
543 NonViralName childName = HibernateProxyHelper.deproxy(childTaxon.getName(), NonViralName.class);
544 fillMissingEpithets(parentName, childName);
545 }
546
547 /**
548 * If the child name is missing genus or species epithet information and the rank is below <i>genus</i>
549 * or <i>species</i> respectively the according epithets are taken from the parent name.
550 * If the name is an autonym and has no combination author/basionym author the authors are taken from
551 * the parent.
552 * @param parentTaxon
553 * @param childTaxon
554 */
555 protected void fillMissingEpithets(NonViralName parentName, NonViralName childName) {
556 if (CdmUtils.isEmpty(childName.getGenusOrUninomial()) && childName.getRank().isLower(Rank.GENUS()) ){
557 childName.setGenusOrUninomial(parentName.getGenusOrUninomial());
558 }
559
560 if (CdmUtils.isEmpty(childName.getSpecificEpithet()) && childName.getRank().isLower(Rank.SPECIES()) ){
561 childName.setSpecificEpithet(parentName.getSpecificEpithet());
562 }
563 if (childName.isAutonym() && childName.getCombinationAuthorTeam() == null && childName.getBasionymAuthorTeam() == null ){
564 childName.setCombinationAuthorTeam(parentName.getCombinationAuthorTeam());
565 childName.setBasionymAuthorTeam(parentName.getBasionymAuthorTeam());
566 }
567 }
568
569 /**
570 * Returns the taxon description for a taxon. If there are multiple taxon descriptions
571 * an arbitrary one is chosen.
572 * If no taxon description exists, a new one is created if <code>createNewIfNotExists</code>
573 * is <code>true</code>.
574 * @param createNewIfNotExists
575 * @param isImageGallery if true only taxon description being image galleries are considered.
576 * If false only taxon description being no image galleries are considered.
577 * @return
578 */
579 public TaxonDescription getTaxonDescription(Taxon taxon, boolean isImageGallery, boolean createNewIfNotExists) {
580 TaxonDescription result = null;
581 Set<TaxonDescription> descriptions= taxon.getDescriptions();
582 for (TaxonDescription description : descriptions){
583 if (description.isImageGallery() == isImageGallery){
584 result = description;
585 break;
586 }
587 }
588 if (result == null && createNewIfNotExists){
589 result = TaxonDescription.NewInstance(taxon);
590 result.setImageGallery(isImageGallery);
591 }
592 return result;
593 }
594
595
596 /**
597 * Returns the accepted taxon of a {@link TaxonBase taxon base}. <BR>
598 * If taxonBase is of type taxon the same object is returned. If taxonBase is of type
599 * synonym the accepted taxon is returned if one exists. If no accepted taxon exists
600 * <code>null</code> is returned. If multiple accepted taxa exist the one taxon with the
601 * same secundum reference is returned. If no such single taxon exists an
602 * {@link IllegalStateException illegal state exception} is thrown.
603 * @param taxonBase
604 * @return
605 */
606 protected Taxon getAcceptedTaxon(TaxonBase<?> taxonBase) {
607 if (taxonBase == null){
608 return null;
609 }else if(taxonBase.isInstanceOf(Taxon.class)){
610 return CdmBase.deproxy(taxonBase, Taxon.class);
611 }else if(taxonBase.isInstanceOf(Synonym.class)){
612 Synonym synonym = CdmBase.deproxy(taxonBase, Synonym.class);
613 Set<Taxon> acceptedTaxa = synonym.getAcceptedTaxa();
614 if (acceptedTaxa.size() == 0){
615 return null;
616 }else if (acceptedTaxa.size() == 1){
617 return acceptedTaxa.iterator().next();
618 }else{
619 Reference sec = synonym.getSec();
620 if (sec != null){
621 Set<Taxon> taxaWithSameSec = new HashSet<Taxon>();
622 for (Taxon taxon: acceptedTaxa){
623 if (sec.equals(taxon.getSec())){
624 taxaWithSameSec.add(taxon);
625 }
626 }
627 if (taxaWithSameSec.size() == 1){
628 return taxaWithSameSec.iterator().next();
629 }
630 }
631 throw new IllegalStateException("Can't define the one accepted taxon for a synonym out of multiple accept taxa");
632 }
633 }else{
634 throw new IllegalStateException("Unknown TaxonBase subclass: " + taxonBase.getClass().getName());
635 }
636 }
637
638
639
640 /**
641 * @param derivedUnitFacade
642 * @param multimediaObject
643 * @throws MalformedURLException
644 */
645 protected Media getImageMedia(String multimediaObject, boolean readDataFromUrl) throws MalformedURLException {
646 if( multimediaObject == null){
647 return null;
648 } else {
649 ImageInfo imd = null;
650 URI uri;
651 try {
652 uri = new URI(multimediaObject);
653 try {
654 if (readDataFromUrl){
655 imd = ImageInfo.NewInstance(uri, 0);
656 }
657 } catch (Exception e) {
658 String message = "An error occurred when trying to read image meta data: " + e.getMessage();
659 logger.warn(message);
660 }
661 ImageFile imf = ImageFile.NewInstance(uri, null, imd);
662 MediaRepresentation representation = MediaRepresentation.NewInstance();
663 representation.setMimeType(imd.getMimeType());
664 representation.addRepresentationPart(imf);
665 Media media = Media.NewInstance();
666 media.addRepresentation(representation);
667 return media;
668 } catch (URISyntaxException e1) {
669 String message = "An URISyntaxException occurred when trying to create uri from multimedia objcet string: " + multimediaObject;
670 logger.warn(message);
671 return null;
672 }
673 }
674 }
675
676
677 }