2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.cdm
.io
.berlinModel
.in
;
11 import static eu
.etaxonomy
.cdm
.io
.berlinModel
.BerlinModelTransformer
.NAME_FACT_ALSO_PUBLISHED_IN
;
12 import static eu
.etaxonomy
.cdm
.io
.berlinModel
.BerlinModelTransformer
.NAME_FACT_BIBLIOGRAPHY
;
13 import static eu
.etaxonomy
.cdm
.io
.berlinModel
.BerlinModelTransformer
.NAME_FACT_PROTOLOGUE
;
16 import java
.io
.IOException
;
17 import java
.net
.MalformedURLException
;
18 import java
.net
.URISyntaxException
;
20 import java
.sql
.ResultSet
;
21 import java
.sql
.SQLException
;
22 import java
.util
.HashMap
;
23 import java
.util
.HashSet
;
27 import org
.apache
.commons
.lang3
.StringUtils
;
28 import org
.apache
.http
.HttpException
;
29 import org
.apache
.logging
.log4j
.LogManager
;
30 import org
.apache
.logging
.log4j
.Logger
;
31 import org
.springframework
.stereotype
.Component
;
33 import eu
.etaxonomy
.cdm
.api
.service
.media
.MediaInfoFileReader
;
34 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
35 import eu
.etaxonomy
.cdm
.common
.URI
;
36 import eu
.etaxonomy
.cdm
.common
.media
.CdmImageInfo
;
37 import eu
.etaxonomy
.cdm
.io
.berlinModel
.in
.validation
.BerlinModelNameFactsImportValidator
;
38 import eu
.etaxonomy
.cdm
.io
.common
.IOValidator
;
39 import eu
.etaxonomy
.cdm
.io
.common
.ResultSetPartitioner
;
40 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
41 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
42 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
43 import eu
.etaxonomy
.cdm
.model
.description
.TaxonNameDescription
;
44 import eu
.etaxonomy
.cdm
.model
.description
.TextData
;
45 import eu
.etaxonomy
.cdm
.model
.media
.ExternalLinkType
;
46 import eu
.etaxonomy
.cdm
.model
.media
.ImageFile
;
47 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
48 import eu
.etaxonomy
.cdm
.model
.media
.MediaRepresentation
;
49 import eu
.etaxonomy
.cdm
.model
.media
.MediaRepresentationPart
;
50 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
51 import eu
.etaxonomy
.cdm
.model
.reference
.OriginalSourceType
;
52 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
59 public class BerlinModelNameFactsImport
extends BerlinModelImportBase
{
60 private static final long serialVersionUID
= 4174085686074314138L;
62 private static final Logger logger
= LogManager
.getLogger();
64 public static final String NAMESPACE
= "NameFact";
67 * write info message after modCount iterations
69 private int modCount
= 500;
70 private static final String pluralString
= "name facts";
71 private static final String dbTableName
= "NameFact";
74 public BerlinModelNameFactsImport(){
75 super(dbTableName
, pluralString
);
80 protected String
getIdQuery(BerlinModelImportState state
) {
81 if (isNotBlank(state
.getConfig().getNameIdTable())){
82 String result
= super.getIdQuery(state
);
83 result
+= " WHERE ptNameFk IN (SELECT NameId FROM " + state
.getConfig().getNameIdTable() + ")";
84 if (state
.getConfig().isEuroMed()){
85 result
+= " AND NOT (NameFactCategoryFk = 3 AND NameFactRefFk = 8500000) "; //#7796#note-11
89 return super.getIdQuery(state
);
94 protected String
getRecordQuery(BerlinModelImportConfigurator config
) {
96 " SELECT NameFact.*, Name.NameID as nameId, NameFactCategory.NameFactCategory " +
97 " FROM NameFact INNER JOIN " +
98 " Name ON NameFact.PTNameFk = Name.NameId INNER JOIN "+
99 " NameFactCategory ON NameFactCategory.NameFactCategoryID = NameFact.NameFactCategoryFK " +
100 " WHERE (NameFactId IN ("+ ID_LIST_TOKEN
+") )";
105 public boolean doPartition(@SuppressWarnings("rawtypes") ResultSetPartitioner partitioner
, BerlinModelImportState state
) {
106 boolean success
= true ;
107 BerlinModelImportConfigurator config
= state
.getConfig();
108 Set
<TaxonName
> nameToSave
= new HashSet
<>();
109 @SuppressWarnings("unchecked")
110 Map
<String
, TaxonName
> nameMap
= partitioner
.getObjectMap(BerlinModelTaxonNameImport
.NAMESPACE
);
111 @SuppressWarnings("unchecked")
112 Map
<String
, Reference
> refMap
= partitioner
.getObjectMap(BerlinModelReferenceImport
.REFERENCE_NAMESPACE
);
114 ResultSet rs
= partitioner
.getResultSet();
116 Reference sourceRef
= state
.getTransactionalSourceReference();
120 while (rs
.next() && (config
.getMaximumNumberOfNameFacts() == 0 || i
< config
.getMaximumNumberOfNameFacts())){
122 if ((i
++ % modCount
) == 0 && i
!= 1 ){ logger
.info("NameFacts handled: " + (i
-1));}
124 int nameFactId
= rs
.getInt("nameFactId");
125 int nameId
= rs
.getInt("nameId");
126 Object nameFactRefFkObj
= rs
.getObject("nameFactRefFk");
127 String nameFactRefDetail
= rs
.getString("nameFactRefDetail");
129 String category
= CdmUtils
.Nz(rs
.getString("NameFactCategory"));
130 String nameFact
= CdmUtils
.Nz(rs
.getString("nameFact"));
132 TaxonName taxonName
= nameMap
.get(String
.valueOf(nameId
));
133 String nameFactRefFk
= String
.valueOf(nameFactRefFkObj
);
134 Reference citation
= refMap
.get(nameFactRefFk
);
136 if (taxonName
!= null){
138 if (category
.equalsIgnoreCase(NAME_FACT_PROTOLOGUE
)){
140 String uriString
= config
.getMediaUrl() + "/" + nameFact
;
142 //this depends on specific project implementation, maybe also config.getMediaPath() is important
143 URI uri
= URI
.create(uriString
);
144 taxonName
.addProtologue(uri
, null, ExternalLinkType
.Unknown
);
145 }catch(IllegalArgumentException e
){
146 logger
.warn("Incorrect protologue URI: " + uriString
);
149 //end NAME_FACT_PROTOLOGUE
150 }else if (category
.equalsIgnoreCase(NAME_FACT_ALSO_PUBLISHED_IN
)){
151 if (StringUtils
.isNotBlank(nameFact
)){
152 TaxonNameDescription description
= TaxonNameDescription
.NewInstance();
153 TextData additionalPublication
= TextData
.NewInstance(Feature
.ADDITIONAL_PUBLICATION());
155 Language language
= Language
.DEFAULT();
156 additionalPublication
.putText(language
, nameFact
);
157 additionalPublication
.addSource(OriginalSourceType
.Import
, String
.valueOf(nameFactId
), NAMESPACE
, null,null, null, null);
158 if (citation
!= null || isNotBlank(nameFactRefDetail
)){
159 additionalPublication
.addSource(OriginalSourceType
.PrimaryTaxonomicSource
, null, null, citation
, nameFactRefDetail
, null, null);
161 description
.addElement(additionalPublication
);
162 taxonName
.addDescription(description
);
164 }else if (category
.equalsIgnoreCase(NAME_FACT_BIBLIOGRAPHY
)){
165 if (isNotBlank(nameFact
)){
166 TaxonNameDescription description
= TaxonNameDescription
.NewInstance();
167 TextData bibliography
= TextData
.NewInstance(Feature
.CITATION());
169 Language language
= Language
.DEFAULT();
170 bibliography
.putText(language
, nameFact
);
171 bibliography
.addSource(OriginalSourceType
.Import
, String
.valueOf(nameFactId
), NAMESPACE
, null,null, null, null);
172 if (citation
!= null || isNotBlank(nameFactRefDetail
)){
173 bibliography
.addSource(OriginalSourceType
.PrimaryTaxonomicSource
, null, null, citation
, nameFactRefDetail
, null, null);
175 description
.addElement(bibliography
);
176 taxonName
.addDescription(description
);
180 logger
.warn("NameFactCategory '" + category
+ "' not yet implemented");
185 // DoubtfulFlag bit Checked
186 // PublishFlag bit Checked
187 // Created_When datetime Checked
188 // Updated_When datetime Checked
189 // Created_Who nvarchar(255) Checked
190 // Updated_Who nvarchar(255) Checked
191 // Notes nvarchar(1000) Checked
193 nameToSave
.add(taxonName
);
196 logger
.warn("TaxonName for NameFact " + nameFactId
+ " does not exist in store");
201 if (config
.getMaximumNumberOfNameFacts() != 0 && i
>= config
.getMaximumNumberOfNameFacts() - 1){
202 logger
.warn("ONLY " + config
.getMaximumNumberOfNameFacts() + " NAMEFACTS imported !!!" )
204 logger
.info("Names to save: " + nameToSave
.size());
205 getNameService().save(nameToSave
);
207 } catch (SQLException e
) {
208 logger
.error("SQLException:" + e
);
214 public Map
<Object
, Map
<String
, ?
extends CdmBase
>> getRelatedObjectsForPartition(ResultSet rs
, BerlinModelImportState state
) {
218 Map
<Object
, Map
<String
, ?
extends CdmBase
>> result
= new HashMap
<>();
221 Set
<String
> nameIdSet
= new HashSet
<>();
222 Set
<String
> referenceIdSet
= new HashSet
<>();
224 handleForeignKey(rs
, nameIdSet
, "PTnameFk");
225 handleForeignKey(rs
, referenceIdSet
, "nameFactRefFk");
229 nameSpace
= BerlinModelTaxonNameImport
.NAMESPACE
;
231 Map
<String
, TaxonName
> objectMap
= getCommonService().getSourcedObjectsByIdInSourceC(TaxonName
.class, idSet
, nameSpace
);
232 result
.put(nameSpace
, objectMap
);
235 nameSpace
= BerlinModelReferenceImport
.REFERENCE_NAMESPACE
;
236 idSet
= referenceIdSet
;
237 Map
<String
, Reference
> referenceMap
= getCommonService().getSourcedObjectsByIdInSourceC(Reference
.class, idSet
, nameSpace
);
238 result
.put(nameSpace
, referenceMap
);
241 } catch (SQLException e
) {
242 throw new RuntimeException(e
);
247 //FIXME gibt es da keine allgemeine Methode in common?
248 public Media
getMedia(String nameFact
, URL mediaUrl
, File mediaPath
){
249 if (mediaUrl
== null){
250 logger
.warn("Media Url should not be null");
253 String mimeTypeTif
= "image/tiff";
254 String mimeTypeJpg
= "image/jpeg";
255 String mimeTypePng
= "image/png";
256 String mimeTypePdf
= "application/pdf";
257 String suffixTif
= "tif";
258 String suffixJpg
= "jpg";
259 String suffixPng
= "png";
260 String suffixPdf
= "pdf";
262 String sep
= File
.separator
;
265 logger
.debug("Getting media for NameFact: " + nameFact
);
267 Media media
= Media
.NewInstance();
269 String mediaUrlString
= mediaUrl
.toString();
272 String urlStringTif
= mediaUrlString
+ "tif/" + nameFact
+ "." + suffixTif
;
273 File file
= new File(mediaPath
, "tif" + sep
+ nameFact
+ "." + suffixTif
);
274 MediaRepresentation representationTif
= MediaRepresentation
.NewInstance(mimeTypeTif
, suffixTif
);
276 representationTif
.addRepresentationPart(makeImage(urlStringTif
, size
, file
));
278 if(representationTif
.getParts().size() > 0){
279 media
.addRepresentation(representationTif
);
283 boolean fileExists
= true;
285 MediaRepresentation representationJpg
= MediaRepresentation
.NewInstance(mimeTypeJpg
, suffixJpg
);
287 String urlStringJpeg
= mediaUrlString
+ "cmd_jpg/" + nameFact
+ "_page_000" + jpgCount
+ "." + suffixJpg
;
288 file
= new File(mediaPath
, "cmd_jpg" + sep
+ nameFact
+ "_page_000" + jpgCount
+ "." + suffixJpg
);
291 representationJpg
.addRepresentationPart(makeImage(urlStringJpeg
, size
, file
));
296 if(representationJpg
.getParts().size() > 0){
297 media
.addRepresentation(representationJpg
);
301 String urlStringPng
= mediaUrlString
+ "png/" + nameFact
+ "." + suffixPng
;
302 file
= new File(mediaPath
, "png" + sep
+ nameFact
+ "." + suffixPng
);
303 MediaRepresentation representationPng
= MediaRepresentation
.NewInstance(mimeTypePng
, suffixPng
);
305 representationPng
.addRepresentationPart(makeImage(urlStringPng
, size
, file
));
311 urlStringPng
= mediaUrlString
+ "png/" + nameFact
+ "00" + pngCount
+ "." + suffixPng
;
312 file
= new File(mediaPath
, "png" + sep
+ nameFact
+ "00" + pngCount
+ "." + suffixPng
);
315 representationPng
.addRepresentationPart(makeImage(urlStringPng
, size
, file
));
321 if(representationPng
.getParts().size() > 0){
322 media
.addRepresentation(representationPng
);
326 String urlStringPdf
= mediaUrlString
+ "pdf/" + nameFact
+ "." + suffixPdf
;
329 uriPdf
= new URI(urlStringPdf
);
330 file
= new File(mediaPath
, "pdf" + sep
+ nameFact
+ "." + suffixPdf
);
331 MediaRepresentation representationPdf
= MediaRepresentation
.NewInstance(mimeTypePdf
, suffixPdf
);
333 representationPdf
.addRepresentationPart(MediaRepresentationPart
.NewInstance(uriPdf
, size
));
339 urlStringPdf
= mediaUrlString
+ "pdf/" + nameFact
+ "00" + pdfCount
+ "." + suffixPdf
;
340 file
= new File(mediaPath
, "pdf/" + sep
+ nameFact
+ "00" + pdfCount
+ "." + suffixPdf
);
343 representationPdf
.addRepresentationPart(MediaRepresentationPart
.NewInstance(uriPdf
, size
));
349 if(representationPdf
.getParts().size() > 0){
350 media
.addRepresentation(representationPdf
);
352 } catch (URISyntaxException e
) {
354 logger
.error("URISyntaxException" + urlStringPdf
);
358 if(logger
.isDebugEnabled()){
359 for (MediaRepresentation rep
: media
.getRepresentations()){
360 for (MediaRepresentationPart part
: rep
.getParts()){
361 logger
.debug("in representation: " + part
.getUri());
369 private ImageFile
makeImage(String imageUri
, Integer size
, File file
){
370 CdmImageInfo imageMetaData
= null;
373 uri
= new URI(imageUri
);
375 //imageMetaData = CdmImageInfo.NewInstance(uri, 0);
376 imageMetaData
= MediaInfoFileReader
.legacyFactoryMethod(uri
)
379 } catch (IOException e
) {
380 logger
.error("IOError reading image metadata." , e
);
381 } catch (HttpException e
) {
382 logger
.error("HttpException reading image metadata." , e
);
384 ImageFile image
= ImageFile
.NewInstance(uri
, size
, imageMetaData
);
386 } catch (URISyntaxException e1
) {
387 logger
.warn("URISyntaxException: " + imageUri
);
394 protected boolean doCheck(BerlinModelImportState state
){
395 IOValidator
<BerlinModelImportState
> validator
= new BerlinModelNameFactsImportValidator();
396 return validator
.validate(state
);
400 protected boolean isIgnore(BerlinModelImportState state
){
401 return ! state
.getConfig().isDoNameFacts();
405 public static void main(String
[] args
) {
407 BerlinModelNameFactsImport nf
= new BerlinModelNameFactsImport();
411 url
= new URL("http://wp5.e-taxonomy.eu/dataportal/cichorieae/media/protolog/");
412 File path
= new File("/Volumes/protolog/protolog/");
414 String fact
= "Acanthocephalus_amplexifolius";
415 // make getMedia public for this to work
416 Media media
= nf
.getMedia(fact
, url
, path
);
418 for (MediaRepresentation rep
: media
.getRepresentations()){
419 logger
.info(rep
.getMimeType());
420 for (MediaRepresentationPart part
: rep
.getParts()){
421 logger
.info(part
.getUri());
425 } catch (MalformedURLException e
) {