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