minor
[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.Set;
18 import java.util.UUID;
19
20 import org.apache.log4j.Logger;
21
22 import eu.etaxonomy.cdm.common.CdmUtils;
23 import eu.etaxonomy.cdm.common.mediaMetaData.ImageMetaData;
24 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
25 import eu.etaxonomy.cdm.io.common.mapping.IInputTransformer;
26 import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
27 import eu.etaxonomy.cdm.model.common.AnnotationType;
28 import eu.etaxonomy.cdm.model.common.CdmBase;
29 import eu.etaxonomy.cdm.model.common.DescriptionElementSource;
30 import eu.etaxonomy.cdm.model.common.ExtensionType;
31 import eu.etaxonomy.cdm.model.common.IOriginalSource;
32 import eu.etaxonomy.cdm.model.common.ISourceable;
33 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
34 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
35 import eu.etaxonomy.cdm.model.common.Language;
36 import eu.etaxonomy.cdm.model.common.MarkerType;
37 import eu.etaxonomy.cdm.model.common.TermVocabulary;
38 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
39 import eu.etaxonomy.cdm.model.description.Feature;
40 import eu.etaxonomy.cdm.model.description.PresenceTerm;
41 import eu.etaxonomy.cdm.model.description.TaxonDescription;
42 import eu.etaxonomy.cdm.model.location.NamedArea;
43 import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
44 import eu.etaxonomy.cdm.model.location.NamedAreaType;
45 import eu.etaxonomy.cdm.model.media.ImageFile;
46 import eu.etaxonomy.cdm.model.media.Media;
47 import eu.etaxonomy.cdm.model.media.MediaRepresentation;
48 import eu.etaxonomy.cdm.model.name.NonViralName;
49 import eu.etaxonomy.cdm.model.name.Rank;
50 import eu.etaxonomy.cdm.model.reference.Reference;
51 import eu.etaxonomy.cdm.model.taxon.Classification;
52 import eu.etaxonomy.cdm.model.taxon.Taxon;
53
54 /**
55 * @author a.mueller
56 * @created 01.07.2008
57 * @version 1.0
58 */
59 public abstract class CdmImportBase<CONFIG extends IImportConfigurator, STATE extends ImportStateBase> extends CdmIoBase<STATE> implements ICdmImport<CONFIG, STATE>{
60 private static Logger logger = Logger.getLogger(CdmImportBase.class);
61
62 protected Classification makeTree(STATE state, Reference reference){
63 Reference ref = CdmBase.deproxy(reference, Reference.class);
64 String treeName = "Classification (Import)";
65 if (ref != null && CdmUtils.isNotEmpty(ref.getTitleCache())){
66 treeName = ref.getTitleCache();
67 }
68 Classification tree = Classification.NewInstance(treeName);
69 tree.setReference(ref);
70
71
72 // use defined uuid for first tree
73 CONFIG config = (CONFIG)state.getConfig();
74 if (state.countTrees() < 1 ){
75 tree.setUuid(config.getClassificationUuid());
76 }
77 getClassificationService().save(tree);
78 state.putTree(ref, tree);
79 return tree;
80 }
81
82
83 /**
84 * Alternative memory saving method variant of
85 * {@link #makeTree(STATE state, Reference ref)} which stores only the
86 * UUID instead of the full tree in the <code>ImportStateBase</code> by
87 * using <code>state.putTreeUuid(ref, tree);</code>
88 *
89 * @param state
90 * @param ref
91 * @return
92 */
93 protected Classification makeTreeMemSave(STATE state, Reference ref){
94 String treeName = "Classification (Import)";
95 if (ref != null && CdmUtils.isNotEmpty(ref.getTitleCache())){
96 treeName = ref.getTitleCache();
97 }
98 Classification tree = Classification.NewInstance(treeName);
99 tree.setReference(ref);
100
101
102 // use defined uuid for first tree
103 CONFIG config = (CONFIG)state.getConfig();
104 if (state.countTrees() < 1 ){
105 tree.setUuid(config.getClassificationUuid());
106 }
107 getClassificationService().save(tree);
108 state.putTreeUuid(ref, tree);
109 return tree;
110 }
111
112
113 protected ExtensionType getExtensionType(STATE state, UUID uuid, String label, String text, String labelAbbrev){
114 ExtensionType extensionType = state.getExtensionType(uuid);
115 if (extensionType == null){
116 extensionType = (ExtensionType)getTermService().find(uuid);
117 if (extensionType == null){
118 extensionType = ExtensionType.NewInstance(text, label, labelAbbrev);
119 extensionType.setUuid(uuid);
120 ExtensionType.DOI().getVocabulary().addTerm(extensionType);
121 getTermService().save(extensionType);
122 }
123 state.putExtensionType(extensionType);
124 }
125 return extensionType;
126 }
127
128
129 protected MarkerType getMarkerType(STATE state, String keyString) {
130 IInputTransformer transformer = state.getTransformer();
131 MarkerType markerType = null;
132 try {
133 markerType = transformer.getMarkerTypeByKey(keyString);
134 } catch (UndefinedTransformerMethodException e) {
135 logger.info("getMarkerTypeByKey not yet implemented for this import");
136 }
137 if (markerType == null ){
138 UUID uuid;
139 try {
140 uuid = transformer.getMarkerTypeUuid(keyString);
141 return getMarkerType(state, uuid, keyString, keyString, keyString);
142 } catch (UndefinedTransformerMethodException e) {
143 logger.warn("getMarkerTypeUuid not yet implemented for this import");
144 }
145 }
146 return null;
147 }
148
149 protected MarkerType getMarkerType(STATE state, UUID uuid, String label, String text, String labelAbbrev){
150 MarkerType markerType = state.getMarkerType(uuid);
151 if (markerType == null){
152 markerType = (MarkerType)getTermService().find(uuid);
153 if (markerType == null){
154 markerType = MarkerType.NewInstance(label, text, labelAbbrev);
155 markerType.setUuid(uuid);
156 MarkerType.COMPLETE().getVocabulary().addTerm(markerType);
157 getTermService().save(markerType);
158 }
159 state.putMarkerType(markerType);
160 }
161 return markerType;
162 }
163
164 protected AnnotationType getAnnotationType(STATE state, UUID uuid, String label, String text, String labelAbbrev){
165 AnnotationType annotationType = state.getAnnotationType(uuid);
166 if (annotationType == null){
167 annotationType = (AnnotationType)getTermService().find(uuid);
168 if (annotationType == null){
169 annotationType = AnnotationType.NewInstance(label, text, labelAbbrev);
170 annotationType.setUuid(uuid);
171 AnnotationType.EDITORIAL().getVocabulary().addTerm(annotationType);
172 getTermService().save(annotationType);
173 }
174 state.putAnnotationType(annotationType);
175 }
176 return annotationType;
177 }
178
179 /**
180 * Returns a named area for a given uuid by first . If the named area does not
181 * @param state
182 * @param uuid
183 * @param label
184 * @param text
185 * @param labelAbbrev
186 * @param areaType
187 * @param level
188 * @return
189 */
190 protected NamedArea getNamedArea(STATE state, UUID uuid, String label, String text, String labelAbbrev, NamedAreaType areaType, NamedAreaLevel level){
191 NamedArea namedArea = state.getNamedArea(uuid);
192 if (namedArea == null){
193 namedArea = (NamedArea)getTermService().find(uuid);
194 if (namedArea == null){
195 namedArea = NamedArea.NewInstance(text, label, labelAbbrev);
196 namedArea.setType(areaType);
197 namedArea.setLevel(level);
198 namedArea.setUuid(uuid);
199 getTermService().save(namedArea);
200 }
201 state.putNamedArea(namedArea);
202 }
203 return namedArea;
204 }
205
206 /**
207 * Returns a feature for a given uuid by first ...
208 * @param state
209 * @param uuid
210 * @param label
211 * @param text
212 * @param labelAbbrev
213 * @return
214 */
215 protected Feature getFeature(STATE state, UUID uuid, String label, String text, String labelAbbrev){
216 if (uuid == null){
217 return null;
218 }
219 Feature feature = state.getFeature(uuid);
220 if (feature == null){
221 feature = (Feature)getTermService().find(uuid);
222 if (feature == null){
223 feature = Feature.NewInstance(text, label, labelAbbrev);
224 feature.setUuid(uuid);
225 feature.setSupportsTextData(true);
226 //set vocabulary ; FIXME use another user-defined vocabulary
227 UUID uuidFeatureVoc = UUID.fromString("b187d555-f06f-4d65-9e53-da7c93f8eaa8");
228 TermVocabulary<Feature> voc = getVocabularyService().find(uuidFeatureVoc);
229 voc.addTerm(feature);
230 getTermService().save(feature);
231 }
232 state.putFeature(feature);
233 }
234 return feature;
235 }
236
237 /**
238 * Returns a presence term for a given uuid by first ...
239 * @param state
240 * @param uuid
241 * @param label
242 * @param text
243 * @param labelAbbrev
244 * @return
245 */
246 protected PresenceTerm getPresenceTerm(STATE state, UUID uuid, String label, String text, String labelAbbrev){
247 if (uuid == null){
248 return null;
249 }
250 PresenceTerm presenceTerm = state.getPresenceTerm(uuid);
251 if (presenceTerm == null){
252 presenceTerm = (PresenceTerm)getTermService().find(uuid);
253 if (presenceTerm == null){
254 presenceTerm = PresenceTerm.NewInstance(text, label, labelAbbrev);
255 presenceTerm.setUuid(uuid);
256 //set vocabulary ; FIXME use another user-defined vocabulary
257 UUID uuidPresenceVoc = UUID.fromString("adbbbe15-c4d3-47b7-80a8-c7d104e53a05");
258 TermVocabulary<PresenceTerm> voc = getVocabularyService().find(uuidPresenceVoc);
259 voc.addTerm(presenceTerm);
260 getTermService().save(presenceTerm);
261 }
262 state.putPresenceTerm(presenceTerm);
263 }
264 return presenceTerm;
265 }
266
267 /**
268 * Returns a language for a given uuid by first ...
269 * @param state
270 * @param uuid
271 * @param label
272 * @param text
273 * @param labelAbbrev
274 * @return
275 */
276 protected Language getLanguage(STATE state, UUID uuid, String label, String text, String labelAbbrev){
277 if (uuid == null){
278 return null;
279 }
280 Language language = state.getLanguage(uuid);
281 if (language == null){
282 language = (Language)getTermService().find(uuid);
283 if (language == null){
284 language = Language.NewInstance(text, label, labelAbbrev);
285
286 language.setUuid(uuid);
287 //set vocabulary ; FIXME use another user-defined vocabulary
288 UUID uuidLanguageVoc = UUID.fromString("45ac7043-7f5e-4f37-92f2-3874aaaef2de");
289 TermVocabulary<Language> voc = getVocabularyService().find(uuidLanguageVoc);
290 voc.addTerm(language);
291 getTermService().save(language);
292 }
293 state.putLanguage(language);
294 }
295 return language;
296 }
297
298 /**
299 * Adds an orginal source to a sourceable objects (implemented for Identifiable entity and description element.
300 * If cdmBase is not sourceable nothing happens.
301 * TODO Move to DbImportBase once this exists.
302 * TODO also implemented in DbImportObjectCreationMapper (reduce redundance)
303 * @param rs
304 * @param cdmBase
305 * @param dbIdAttribute
306 * @param namespace
307 * @param citation
308 * @throws SQLException
309 */
310 public void addOriginalSource(CdmBase cdmBase, Object idAttributeValue, String namespace, Reference citation) throws SQLException {
311 if (cdmBase instanceof ISourceable ){
312 IOriginalSource source;
313 ISourceable sourceable = (ISourceable)cdmBase;
314 Object id = idAttributeValue;
315 String strId = String.valueOf(id);
316 String microCitation = null;
317 if (cdmBase instanceof IdentifiableEntity){
318 source = IdentifiableSource.NewInstance(strId, namespace, citation, microCitation);
319 }else if (cdmBase instanceof DescriptionElementBase){
320 source = DescriptionElementSource.NewInstance(strId, namespace, citation, microCitation);
321 }else{
322 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.");
323 return;
324 }
325 sourceable.addSource(source);
326 }
327 }
328
329 /**
330 * @see #addOriginalSource(CdmBase, Object, String, Reference)
331 * @param rs
332 * @param cdmBase
333 * @param dbIdAttribute
334 * @param namespace
335 * @param citation
336 * @throws SQLException
337 */
338 public void addOriginalSource(ResultSet rs, CdmBase cdmBase, String dbIdAttribute, String namespace, Reference citation) throws SQLException {
339 Object id = rs.getObject(dbIdAttribute);
340 addOriginalSource(cdmBase, id, namespace, citation);
341 }
342
343
344 /**
345 * If the child taxon is missing genus or species epithet information and the rank is below <i>genus</i>
346 * or <i>species</i> respectively the according epithets are taken from the parent taxon.
347 * If the name is an autonym and has no combination author/basionym author the authors are taken from
348 * the parent.
349 * @param parentTaxon
350 * @param childTaxon
351 */
352 protected void fillMissingEpithetsForTaxa(Taxon parentTaxon, Taxon childTaxon) {
353 NonViralName parentName = HibernateProxyHelper.deproxy(parentTaxon.getName(), NonViralName.class);
354 NonViralName childName = HibernateProxyHelper.deproxy(childTaxon.getName(), NonViralName.class);
355 fillMissingEpithets(parentName, childName);
356 }
357
358 /**
359 * If the child name is missing genus or species epithet information and the rank is below <i>genus</i>
360 * or <i>species</i> respectively the according epithets are taken from the parent name.
361 * If the name is an autonym and has no combination author/basionym author the authors are taken from
362 * the parent.
363 * @param parentTaxon
364 * @param childTaxon
365 */
366 protected void fillMissingEpithets(NonViralName parentName, NonViralName childName) {
367 if (CdmUtils.isEmpty(childName.getGenusOrUninomial()) && childName.getRank().isLower(Rank.GENUS()) ){
368 childName.setGenusOrUninomial(parentName.getGenusOrUninomial());
369 }
370
371 if (CdmUtils.isEmpty(childName.getSpecificEpithet()) && childName.getRank().isLower(Rank.SPECIES()) ){
372 childName.setSpecificEpithet(parentName.getSpecificEpithet());
373 }
374 if (childName.isAutonym() && childName.getCombinationAuthorTeam() == null && childName.getBasionymAuthorTeam() == null ){
375 childName.setCombinationAuthorTeam(parentName.getCombinationAuthorTeam());
376 childName.setBasionymAuthorTeam(parentName.getBasionymAuthorTeam());
377 }
378 }
379
380 /**
381 * Returns the image gallery for a taxon. If there are multiple taxon descriptions
382 * marked as image galleries an arbitrary one is chosen.
383 * If no image gallery exists, a new one is created if <code>createNewIfNotExists</code>
384 * is <code>true</code>.
385 * @param createNewIfNotExists
386 * @return
387 */
388 public TaxonDescription getTaxonDescription(Taxon taxon, boolean isImageGallery, boolean createNewIfNotExists) {
389 TaxonDescription result = null;
390 Set<TaxonDescription> descriptions= taxon.getDescriptions();
391 for (TaxonDescription description : descriptions){
392 if (description.isImageGallery() == isImageGallery){
393 result = description;
394 break;
395 }
396 }
397 if (result == null && createNewIfNotExists){
398 result = TaxonDescription.NewInstance(taxon);
399 result.setImageGallery(isImageGallery);
400 }
401 return result;
402 }
403
404
405 /**
406 * @param derivedUnitFacade
407 * @param multimediaObject
408 * @throws MalformedURLException
409 */
410 protected Media getImageMedia(String multimediaObject, boolean readDataFromUrl) throws MalformedURLException {
411 if( multimediaObject == null){
412 return null;
413 } else {
414 ImageMetaData imd = ImageMetaData.newInstance();
415 URI uri;
416 try {
417 uri = new URI(multimediaObject);
418 try {
419 if (readDataFromUrl){
420 imd.readMetaData(uri, 0);
421 }
422 } catch (Exception e) {
423 String message = "An error occurred when trying to read image meta data: " + e.getMessage();
424 logger.warn(message);
425 }
426 ImageFile imf = ImageFile.NewInstance(uri, null, imd);
427 MediaRepresentation representation = MediaRepresentation.NewInstance();
428 representation.setMimeType(imd.getMimeType());
429 representation.addRepresentationPart(imf);
430 Media media = Media.NewInstance();
431 media.addRepresentation(representation);
432 return media;
433 } catch (URISyntaxException e1) {
434 String message = "An URISyntaxException occurred when trying to create uri from multimedia objcet string: " + multimediaObject;
435 logger.warn(message);
436 return null;
437 }
438 }
439 }
440
441
442 }