1
|
/**
|
2
|
* Copyright (C) 2016 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
|
package eu.etaxonomy.cdm.io.greece;
|
10
|
|
11
|
import java.io.File;
|
12
|
import java.io.IOException;
|
13
|
import java.net.URI;
|
14
|
import java.util.ArrayList;
|
15
|
import java.util.List;
|
16
|
|
17
|
import org.apache.log4j.Logger;
|
18
|
import org.apache.sanselan.ImageReadException;
|
19
|
import org.apache.sanselan.Sanselan;
|
20
|
import org.apache.sanselan.common.IImageMetadata;
|
21
|
import org.apache.sanselan.common.ImageMetadata.Item;
|
22
|
import org.springframework.stereotype.Component;
|
23
|
import org.springframework.transaction.TransactionStatus;
|
24
|
|
25
|
import eu.etaxonomy.cdm.api.service.config.MatchingTaxonConfigurator;
|
26
|
import eu.etaxonomy.cdm.io.common.CdmImportBase;
|
27
|
import eu.etaxonomy.cdm.io.mexico.SimpleExcelTaxonImportState;
|
28
|
import eu.etaxonomy.cdm.model.agent.Person;
|
29
|
import eu.etaxonomy.cdm.model.common.Language;
|
30
|
import eu.etaxonomy.cdm.model.description.Feature;
|
31
|
import eu.etaxonomy.cdm.model.description.TaxonDescription;
|
32
|
import eu.etaxonomy.cdm.model.description.TextData;
|
33
|
import eu.etaxonomy.cdm.model.media.Media;
|
34
|
import eu.etaxonomy.cdm.model.reference.Reference;
|
35
|
import eu.etaxonomy.cdm.model.taxon.Taxon;
|
36
|
/**
|
37
|
* Import for the Flora Hellenica images.
|
38
|
*
|
39
|
* @author a.mueller
|
40
|
* @date 03.04.2017
|
41
|
*/
|
42
|
|
43
|
@Component
|
44
|
public class FloraHellenicaImageImport<CONFIG extends FloraHellenicaImportConfigurator>
|
45
|
extends CdmImportBase<CONFIG,SimpleExcelTaxonImportState<CONFIG>>{
|
46
|
|
47
|
private static final long serialVersionUID = 7118028793298922703L;
|
48
|
private static final Logger logger = Logger.getLogger(FloraHellenicaImageImport.class);
|
49
|
|
50
|
private static final String BASE_URL = "https://media.e-taxonomy.eu/flora-greece/";
|
51
|
private static final String IMAGE_FOLDER = "////BGBM-PESIHPC/Greece/thumbs/";
|
52
|
|
53
|
/**
|
54
|
* {@inheritDoc}
|
55
|
*/
|
56
|
@Override
|
57
|
protected void doInvoke(SimpleExcelTaxonImportState<CONFIG> state) {
|
58
|
TransactionStatus tx = this.startTransaction();
|
59
|
for (int plate = 1; plate < 22 ; plate++){
|
60
|
try {
|
61
|
handleSinglePlate(state, plate);
|
62
|
} catch (Exception e) {
|
63
|
logger.error("Error when handling plate " + plate);
|
64
|
e.printStackTrace();
|
65
|
}
|
66
|
}
|
67
|
this.commitTransaction(tx);
|
68
|
}
|
69
|
|
70
|
/**
|
71
|
* @param state
|
72
|
* @param plate
|
73
|
*/
|
74
|
private void handleSinglePlate(SimpleExcelTaxonImportState<CONFIG> state, int plate) {
|
75
|
String fill = plate < 10 ? "0" : "";
|
76
|
String plateStr = "Plate_" + fill + plate + "/";
|
77
|
String fullFolderUrl = BASE_URL + plateStr;
|
78
|
String fullThumbUrl = BASE_URL + "thumbs/" + plateStr;
|
79
|
String folderStr = IMAGE_FOLDER + plateStr;
|
80
|
File file = new File(folderStr);
|
81
|
String[] list = file.list();
|
82
|
for (String fileStr : list){
|
83
|
try {
|
84
|
handleSingleFile(state, fullFolderUrl, fullThumbUrl, fileStr);
|
85
|
} catch (Exception e) {
|
86
|
logger.error("Error when handling file: " + fileStr + " in plate " + plate);
|
87
|
e.printStackTrace();
|
88
|
}
|
89
|
}
|
90
|
}
|
91
|
|
92
|
/**
|
93
|
* @param state
|
94
|
* @param fullFolderUrl
|
95
|
* @param fullThumbUrl
|
96
|
* @param fileStr
|
97
|
*/
|
98
|
private void handleSingleFile(SimpleExcelTaxonImportState<CONFIG> state, String fullFolderUrl, String fullThumbUrl, String fileStr) {
|
99
|
String[] taxonNameAndArtist = getTaxonName(fileStr);
|
100
|
String taxonNameStr = taxonNameAndArtist[0];
|
101
|
String taxonNameStr2 = null;
|
102
|
String artistStr = taxonNameAndArtist[1];
|
103
|
if (fileStr.equals("RamondaSerbica(L)+Nathaliae(R)1.jpg")){
|
104
|
taxonNameStr = "Ramonda serbica";
|
105
|
taxonNameStr2 = "Ramonda nathaliae";
|
106
|
}
|
107
|
|
108
|
try {
|
109
|
|
110
|
Media media = getImageMedia(fullFolderUrl + fileStr, fullThumbUrl + fileStr, true);
|
111
|
|
112
|
//image metadata
|
113
|
URI uri = URI.create(fullThumbUrl + fileStr);
|
114
|
try{
|
115
|
IImageMetadata metadata = Sanselan.getMetadata(uri.toURL().openStream(), null);
|
116
|
ArrayList<?> items = metadata.getItems();
|
117
|
for (Object object : items){
|
118
|
Item item = (Item) object;
|
119
|
// System.out.println(item.getKeyword() + ": " + item.getText());
|
120
|
String keyword = item.getKeyword().toLowerCase();
|
121
|
String value = item.getText();
|
122
|
if("image description".equals(keyword)){
|
123
|
media.putDescription(Language.DEFAULT(), value);
|
124
|
}else if ("artist".equals(item.getKeyword().toLowerCase())){
|
125
|
if (isNotBlank(artistStr) && ! value.contains(artistStr)){
|
126
|
logger.warn("Artist and artistStr are different: " + artistStr + "; " + value);
|
127
|
}
|
128
|
artistStr = value;
|
129
|
}
|
130
|
}
|
131
|
} catch (ImageReadException | IOException e1) {
|
132
|
e1.printStackTrace();
|
133
|
}
|
134
|
if (isNotBlank(artistStr)){
|
135
|
Person person = Person.NewInstance();
|
136
|
person.setLastname(artistStr);
|
137
|
media.setArtist(person);
|
138
|
}
|
139
|
|
140
|
media.addPrimaryMediaSource(getSecReference(state), null);
|
141
|
|
142
|
|
143
|
Taxon taxon = getAcceptedTaxon(taxonNameStr);
|
144
|
makeTextData(fileStr, media, taxon);
|
145
|
if (taxonNameStr2 != null){
|
146
|
getAcceptedTaxon(taxonNameStr);
|
147
|
makeTextData(fileStr, media, taxon);
|
148
|
}
|
149
|
|
150
|
|
151
|
if (taxonNameStr2 == null){
|
152
|
media.putTitle(Language.LATIN(), taxon == null ? "taxonNameStr" :
|
153
|
taxon.getName().getTitleCache());
|
154
|
}else{
|
155
|
media.putTitle(Language.LATIN(), "Ramonda serbica(L) + R. nathaliae(R)");
|
156
|
}
|
157
|
|
158
|
|
159
|
} catch (Exception e) {
|
160
|
e.printStackTrace();
|
161
|
return;
|
162
|
}
|
163
|
}
|
164
|
|
165
|
private Reference secReference;
|
166
|
private Reference getSecReference(SimpleExcelTaxonImportState<CONFIG> state) {
|
167
|
if (secReference != null){
|
168
|
secReference = getReferenceService().find(state.getConfig().getSecReference().getUuid());
|
169
|
}
|
170
|
return secReference;
|
171
|
}
|
172
|
|
173
|
/**
|
174
|
* @param fileStr
|
175
|
* @param media
|
176
|
* @param taxon
|
177
|
* @return
|
178
|
*/
|
179
|
private void makeTextData(String fileStr, Media media, Taxon taxon) {
|
180
|
if (taxon == null){
|
181
|
logger.warn("Taxon not found for image " + fileStr + "."
|
182
|
+ "Media could not be attached to taxon.");
|
183
|
getMediaService().saveOrUpdate(media);
|
184
|
return;
|
185
|
}
|
186
|
TaxonDescription imageGallery = taxon.getImageGallery(true);
|
187
|
TextData textData = TextData.NewInstance();
|
188
|
textData.setFeature(Feature.IMAGE());
|
189
|
imageGallery.addElement(textData);
|
190
|
textData.addMedia(media);
|
191
|
}
|
192
|
|
193
|
/**
|
194
|
* @param taxonNameStr
|
195
|
* @return
|
196
|
*/
|
197
|
private Taxon getAcceptedTaxon(String taxonNameStr) {
|
198
|
|
199
|
MatchingTaxonConfigurator config = new MatchingTaxonConfigurator();
|
200
|
config.setTaxonNameTitle(taxonNameStr);
|
201
|
config.setIncludeSynonyms(false);
|
202
|
List<Taxon> list = (List)getTaxonService().findTaxaByName(config);
|
203
|
if (list.isEmpty()){
|
204
|
logger.warn("Taxon not found for media: " + taxonNameStr);
|
205
|
return null;
|
206
|
}else{
|
207
|
if (list.size()>1){
|
208
|
logger.warn("More than 1 taxon found for media: " + taxonNameStr);
|
209
|
}
|
210
|
return list.get(0);
|
211
|
}
|
212
|
}
|
213
|
|
214
|
/**
|
215
|
* @param fileStr
|
216
|
* @return
|
217
|
*/
|
218
|
private String[] getTaxonName(String fileStr) {
|
219
|
String[] result = new String[2];
|
220
|
fileStr = fileStr.split("\\.")[0];
|
221
|
fileStr = fileStr.replaceAll("[0-9]", "");
|
222
|
String[] x = fileStr.split("_");
|
223
|
if (x.length == 2){
|
224
|
result[1] = x[1];
|
225
|
}
|
226
|
|
227
|
fileStr = splitCamelCase(x[0]);
|
228
|
String[] split = fileStr.split(" ");
|
229
|
String name = split[0] + " " + split[1].toLowerCase() +
|
230
|
(split.length > 2 ? " subsp. " + split[2].toLowerCase() : "");
|
231
|
result[0] = name;
|
232
|
System.out.println(result[0] + (result[1] != null ? " Artist: " + result[1]: ""));
|
233
|
return result;
|
234
|
}
|
235
|
|
236
|
//from http://stackoverflow.com/questions/2559759/how-do-i-convert-camelcase-into-human-readable-names-in-java
|
237
|
static String splitCamelCase(String s) {
|
238
|
return s.replaceAll(
|
239
|
String.format("%s",
|
240
|
// "(?<=[A-Z])(?=[A-Z][a-z])",
|
241
|
"(?<=[^A-Z])(?=[A-Z])"
|
242
|
// "(?<=[A-Za-z])(?=[^A-Za-z])"
|
243
|
),
|
244
|
" "
|
245
|
);
|
246
|
}
|
247
|
|
248
|
/**
|
249
|
* {@inheritDoc}
|
250
|
*/
|
251
|
@Override
|
252
|
protected boolean doCheck(SimpleExcelTaxonImportState<CONFIG> state) {
|
253
|
return false;
|
254
|
}
|
255
|
|
256
|
/**
|
257
|
* {@inheritDoc}
|
258
|
*/
|
259
|
@Override
|
260
|
protected boolean isIgnore(SimpleExcelTaxonImportState<CONFIG> state) {
|
261
|
return ! state.getConfig().isDoImages();
|
262
|
}
|
263
|
|
264
|
|
265
|
|
266
|
}
|