Project

General

Profile

Download (12.2 KB) Statistics
| Branch: | Revision:
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.util.List;
14

    
15
import org.apache.commons.imaging.ImageReadException;
16
import org.apache.commons.imaging.Imaging;
17
import org.apache.commons.imaging.common.GenericImageMetadata.GenericImageMetadataItem;
18
import org.apache.commons.imaging.common.ImageMetadata;
19
import org.apache.commons.imaging.common.ImageMetadata.ImageMetadataItem;
20
import org.apache.log4j.Logger;
21
import org.joda.time.DateTime;
22
import org.joda.time.DateTimeZone;
23
import org.joda.time.format.DateTimeFormat;
24
import org.joda.time.format.DateTimeFormatter;
25
import org.springframework.stereotype.Component;
26
import org.springframework.transaction.TransactionStatus;
27

    
28
import eu.etaxonomy.cdm.api.service.config.MatchingTaxonConfigurator;
29
import eu.etaxonomy.cdm.common.URI;
30
import eu.etaxonomy.cdm.io.common.CdmImportBase;
31
import eu.etaxonomy.cdm.io.mexico.SimpleExcelTaxonImportState;
32
import eu.etaxonomy.cdm.model.agent.Person;
33
import eu.etaxonomy.cdm.model.common.CdmBase;
34
import eu.etaxonomy.cdm.model.common.Language;
35
import eu.etaxonomy.cdm.model.common.TimePeriod;
36
import eu.etaxonomy.cdm.model.description.Feature;
37
import eu.etaxonomy.cdm.model.description.TaxonDescription;
38
import eu.etaxonomy.cdm.model.description.TextData;
39
import eu.etaxonomy.cdm.model.media.Media;
40
import eu.etaxonomy.cdm.model.media.Rights;
41
import eu.etaxonomy.cdm.model.media.RightsType;
42
import eu.etaxonomy.cdm.model.reference.Reference;
43
import eu.etaxonomy.cdm.model.taxon.Synonym;
44
import eu.etaxonomy.cdm.model.taxon.Taxon;
45
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
46
/**
47
 * Import for the Flora Hellenica images.
48
 *
49
 * @author a.mueller
50
 * @since 03.04.2017
51
 */
52
@Component
53
public class FloraHellenicaImageImport<CONFIG extends FloraHellenicaImportConfigurator>
54
        extends CdmImportBase<CONFIG,SimpleExcelTaxonImportState<CONFIG>>{
55

    
56
    private static final long serialVersionUID = 7118028793298922703L;
57
    private static final Logger logger = Logger.getLogger(FloraHellenicaImageImport.class);
58

    
59
    private static final String BASE_URL = "https://media.e-taxonomy.eu/flora-greece/";
60
    private static final String IMAGE_FOLDER = "////BGBM-PESIHPC/Greece/thumbs/";
61

    
62
    @Override
63
    protected void doInvoke(SimpleExcelTaxonImportState<CONFIG> state) {
64
        TransactionStatus tx = this.startTransaction();
65
        for (int plate = 1; plate < 22 ; plate++){
66
            try {
67
                handleSinglePlate(state, plate);
68
            } catch (Exception e) {
69
                logger.error("Error when handling plate " + plate);
70
                e.printStackTrace();
71
            }
72
        }
73
        this.commitTransaction(tx);
74
    }
75

    
76
    private void handleSinglePlate(SimpleExcelTaxonImportState<CONFIG> state, int plate) {
77
        String fill = plate < 10 ? "0" : "";
78
        String plateStr = "Plate_" + fill + plate + "/";
79
        String fullFolderUrl = BASE_URL + plateStr;
80
        String fullThumbUrl = BASE_URL + "thumbs/" + plateStr;
81
        String folderStr = IMAGE_FOLDER + plateStr;
82
        File file = new File(folderStr);
83
        String[] list = file.list();
84
        for (String fileStr : list){
85
            try {
86
                handleSingleFile(state, fullFolderUrl, fullThumbUrl, fileStr, plate);
87
            } catch (Exception e) {
88
                logger.error("Error when handling file: " + fileStr + " in plate " + plate);
89
                e.printStackTrace();
90
            }
91
        }
92
    }
93

    
94
    private void handleSingleFile(SimpleExcelTaxonImportState<CONFIG> state,
95
            String fullFolderUrl, String fullThumbUrl, String fileStr, int plate) {
96
        String[] taxonNameAndArtist = getTaxonName(fileStr);
97
        String taxonNameStr = taxonNameAndArtist[0];
98
        String taxonNameStr2 = null;
99
        String artistStr = taxonNameAndArtist[1];
100
        if (fileStr.equals("RamondaSerbica(L)+Nathaliae(R)1.jpg")){
101
            taxonNameStr = "Ramonda serbica";
102
            taxonNameStr2 = "Ramonda nathaliae";
103
        }else if (fileStr.contains("HypericumCerastioides")){
104
            taxonNameStr = taxonNameStr.replace("HypericumCerastoides", "HypericumCerastioides");
105
        }else if (fileStr.contains("StachysScardica")){
106
            taxonNameStr = taxonNameStr.replace("StachysScardica", "BetonicaScardica");
107
        }else if (fileStr.contains("OleaEuropaeaOleaster ")){
108
            taxonNameStr = taxonNameStr.replace("OleaEuropaeaOleaster", "OleaEuropaeaEuropaea");
109
        }
110

    
111
        try {
112

    
113
            Media media = getImageMedia(fullFolderUrl + fileStr, fullThumbUrl + fileStr, true);
114

    
115
            //image metadata
116
            URI uri = URI.create(fullThumbUrl + fileStr);
117
            try{
118
                ImageMetadata metadata = Imaging.getMetadata(uri.toURL().openStream(), null);
119
                List<? extends ImageMetadataItem> items = metadata.getItems();
120
                for (ImageMetadataItem metadataItem : items){
121
                    if (metadataItem instanceof GenericImageMetadataItem){
122
                        GenericImageMetadataItem item = (GenericImageMetadataItem) metadataItem;
123

    
124
    //                    System.out.println(item.getKeyword() +  ":    " + item.getText());
125
                        String keyword = item.getKeyword().toLowerCase();
126
                        String value = removeQuots(item.getText());
127
                        if("image description".equals(keyword)){
128
                            media.putDescription(Language.DEFAULT(), value);
129
                        }else if ("artist".equals(keyword)){
130
                            if (isNotBlank(artistStr) && ! value.contains(artistStr)){
131
                                logger.warn("Artist and artistStr are different: " +  artistStr  + "; " + value);
132
                            }
133
                            artistStr = value;
134
                        }else if ("date time original".equalsIgnoreCase(item.getKeyword())){
135
                            DateTimeFormatter f = DateTimeFormat.forPattern("yyyy:MM:dd HH:mm:ss");
136
                            DateTime created = f.withZone(DateTimeZone.forID("Europe/Athens")).parseDateTime(value);
137
                            media.setMediaCreated(TimePeriod.NewInstance(created));
138
                        }
139
                    }else{
140
                        throw new IllegalStateException("Unsupported ImageMetadataItem type: " + metadataItem.getClass().getName());
141
                    }
142
                }
143
            } catch (ImageReadException | IOException e1) {
144
                e1.printStackTrace();
145
            }
146
            if (isNotBlank(artistStr)){
147
                Person person = Person.NewInstance();
148
                String[] split = artistStr.split("\\+");
149
                if (split.length == 1){
150
                    person.setFamilyName(artistStr);
151
                }else if (split.length == 2){
152
                    person.setGivenName(split[0]);
153
                    person.setFamilyName(split[1]);
154
                }else{
155
                    person.setTitleCache("artistStr", true);
156
                }
157
                person = state.getDeduplicationHelper().getExistingAuthor(state, person);
158

    
159
                media.setArtist(person);
160
                //copyright
161
                Rights right = Rights.NewInstance();
162
                right.setType(RightsType.COPYRIGHT());
163
                right.setAgent(person);
164
                right = state.getDeduplicationHelper().getExistingCopyright(state, right);
165
                media.addRights(right);
166
            }
167

    
168
            String detail = "p. " + FloraHellenicaImageCaptionImport.startPage + 1 + plate *2;
169
            media.addPrimaryMediaSource(getSecReference(state), detail);
170

    
171

    
172
            Taxon taxon = getAcceptedTaxon(taxonNameStr);
173
            makeTextData(fileStr, media, taxon);
174
            if (taxonNameStr2 != null){
175
                Taxon taxon2 = getAcceptedTaxon(taxonNameStr);
176
                makeTextData(fileStr, media, taxon2);
177
            }
178

    
179
            if (taxonNameStr2 == null){
180
                media.putTitle(Language.LATIN(), taxon == null ? taxonNameStr :
181
                    taxon.getName().getTitleCache());
182
            }else{
183
                media.putTitle(Language.LATIN(), "Ramonda serbica(L) + R. nathaliae(R)");
184
            }
185
        } catch (Exception e) {
186
            e.printStackTrace();
187
            return;
188
        }
189
    }
190

    
191
    private String removeQuots(String text) {
192
        if (text.startsWith("'") && text.endsWith("'")){
193
            return text.substring(1, text.length() -1);
194
        }else{
195
            return text;
196
        }
197
    }
198

    
199
    private Reference secReference;
200
    private Reference getSecReference(SimpleExcelTaxonImportState<CONFIG> state) {
201
        if (secReference != null){
202
            secReference = getReferenceService().find(state.getConfig().getSecReference().getUuid());
203
        }
204
        return secReference;
205
    }
206

    
207
    /**
208
     * Gets the image gallery, creates
209
     */
210
    private void makeTextData(String fileStr, Media media, Taxon taxon) {
211
        if (taxon == null){
212
            logger.warn("Taxon not found for image " + fileStr + "."
213
                    + "Media could not be attached to taxon.");
214
            getMediaService().saveOrUpdate(media);
215
            return;
216
        }
217
        TaxonDescription imageGallery = taxon.getImageGallery(true);
218
        TextData textData;
219
        if (imageGallery.getElements().isEmpty()){
220
            textData = TextData.NewInstance();
221
            textData.setFeature(Feature.IMAGE());
222
        }else{
223
            textData = CdmBase.deproxy(imageGallery.getElements().iterator().next(), TextData.class);
224
        }
225
        imageGallery.addElement(textData);
226
        textData.addMedia(media);
227
    }
228

    
229
    private Taxon getAcceptedTaxon(String taxonNameStr) {
230

    
231
        MatchingTaxonConfigurator config = new MatchingTaxonConfigurator();
232
        taxonNameStr = adaptName(taxonNameStr);
233
        config.setTaxonNameTitle(taxonNameStr);
234
        config.setIncludeSynonyms(true);
235
        List<TaxonBase> list = getTaxonService().findTaxaByName(config);
236
        if (list.isEmpty()){
237
            logger.warn("Taxon not found for media: " + taxonNameStr);
238
            return null;
239
        }else{
240
            if (list.size()>1){
241
                logger.warn("More than 1 taxon found for media: " + taxonNameStr);
242
            }
243
            TaxonBase<?> taxonBase = list.get(0);
244
            Taxon result;
245
            if (taxonBase.isInstanceOf(Synonym.class)){
246
                result = CdmBase.deproxy(taxonBase, Synonym.class).getAcceptedTaxon();
247
            }else{
248
                result = CdmBase.deproxy(taxonBase, Taxon.class);
249
            }
250
            return result;
251
        }
252
    }
253

    
254
    private String adaptName(String taxonNameStr) {
255
        if (taxonNameStr.equals("Hypericum cerastoides")){
256
            taxonNameStr = "Hypericum cerastioides";
257
        }
258
        return taxonNameStr;
259
    }
260

    
261
    private String[] getTaxonName(String fileStr) {
262
        String[] result = new String[2];
263
        fileStr = fileStr.split("\\.")[0];
264
        fileStr = fileStr.replaceAll("[0-9]", "");
265
        String[] x = fileStr.split("_");
266
        if (x.length == 2){
267
            result[1] = x[1];
268
        }
269

    
270
        fileStr = splitCamelCase(x[0]);
271
        String[] split = fileStr.split(" ");
272
        String name = split[0] + " " + split[1].toLowerCase() +
273
                (split.length > 2 ? " subsp. " + split[2].toLowerCase() : "");
274
        result[0] = name;
275
        System.out.println(result[0] + (result[1] != null ?  "   Artist: " + result[1]: ""));
276
        return result;
277
    }
278

    
279
    //from http://stackoverflow.com/questions/2559759/how-do-i-convert-camelcase-into-human-readable-names-in-java
280
    static String splitCamelCase(String s) {
281
        return s.replaceAll(
282
            String.format("%s",
283
//              "(?<=[A-Z])(?=[A-Z][a-z])",
284
                "(?<=[^A-Z])(?=[A-Z])"
285
//              "(?<=[A-Za-z])(?=[^A-Za-z])"
286
            ),
287
            " "
288
        );
289
    }
290

    
291
    @Override
292
    protected boolean doCheck(SimpleExcelTaxonImportState<CONFIG> state) {
293
        return false;
294
    }
295

    
296
    @Override
297
    protected boolean isIgnore(SimpleExcelTaxonImportState<CONFIG> state) {
298
        return ! state.getConfig().isDoImages();
299
    }
300
}
(5-5/18)