Project

General

Profile

Download (11.6 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 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.media.in;
10

    
11
import java.util.ArrayList;
12
import java.util.Arrays;
13
import java.util.List;
14
import java.util.Map;
15
import java.util.UUID;
16
import java.util.regex.Matcher;
17
import java.util.regex.Pattern;
18

    
19
import org.joda.time.DateTime;
20
import org.joda.time.DateTimeFieldType;
21
import org.joda.time.Partial;
22
import org.springframework.stereotype.Component;
23

    
24
import eu.etaxonomy.cdm.common.URI;
25
import eu.etaxonomy.cdm.common.media.CdmImageInfo;
26
import eu.etaxonomy.cdm.io.excel.common.ExcelImportBase;
27
import eu.etaxonomy.cdm.io.excel.common.ExcelRowBase;
28
import eu.etaxonomy.cdm.io.media.in.MediaExcelImportConfigurator.MediaTitleEnum;
29
import eu.etaxonomy.cdm.model.agent.AgentBase;
30
import eu.etaxonomy.cdm.model.agent.Person;
31
import eu.etaxonomy.cdm.model.common.Language;
32
import eu.etaxonomy.cdm.model.common.TimePeriod;
33
import eu.etaxonomy.cdm.model.description.TaxonDescription;
34
import eu.etaxonomy.cdm.model.description.TextData;
35
import eu.etaxonomy.cdm.model.media.ImageFile;
36
import eu.etaxonomy.cdm.model.media.Media;
37
import eu.etaxonomy.cdm.model.media.MediaRepresentation;
38
import eu.etaxonomy.cdm.model.media.Rights;
39
import eu.etaxonomy.cdm.model.media.RightsType;
40
import eu.etaxonomy.cdm.model.name.TaxonName;
41
import eu.etaxonomy.cdm.model.reference.Reference;
42
import eu.etaxonomy.cdm.model.taxon.Taxon;
43
import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser;
44

    
45
/**
46
 * @author a.mueller
47
 * @since 30.10.2017
48
 */
49
@Component
50
public class MediaExcelImport
51
        extends ExcelImportBase<MediaExcelImportState, MediaExcelImportConfigurator, ExcelRowBase>{
52

    
53
    private static final long serialVersionUID = -428449749189166794L;
54

    
55
    private static final String COL_TAXON_UUID = "taxonUuid";
56
    private static final String COL_NAME_CACHE = "nameCache";
57
    private static final String COL_NAME_TITLE = "nameTitle";
58
    private static final String COL_TAXON_TITLE = "taxonTitle";
59
    private static final String COL_DESCRIPTION = "description";
60
    private static final String COL_TITLE = "title";
61
    private static final String COL_COPYRIGHT = "copyright";
62
    private static final String COL_ARTIST = "artist";
63
    private static final String COL_DATE = "date";
64

    
65
    @Override
66
    protected void analyzeRecord(Map<String, String> record, MediaExcelImportState state) {
67
        // do nothing
68
    }
69

    
70
    @Override
71
    protected void firstPass(MediaExcelImportState state) {
72
        Map<String, String> record = state.getOriginalRecord();
73
        String line = "row " + state.getCurrentLine() + ": ";
74
        String linePure = "row " + state.getCurrentLine();
75
        System.out.println(linePure);
76

    
77
        //taxon
78
        Taxon taxon = getTaxonByCdmId(state, COL_TAXON_UUID,
79
                COL_NAME_CACHE, COL_NAME_TITLE, COL_TAXON_TITLE,
80
                Taxon.class, linePure);
81

    
82
        //media
83
        Media media = Media.NewInstance();
84

    
85
        //description
86
        String description = record.get(COL_DESCRIPTION);
87
        if (isNotBlank(description)){
88

    
89
            UUID descriptionLanguageUuid = state.getConfig().getDescriptionLanguageUuid();
90
            Language descriptionLanguage = getLanguage(state, descriptionLanguageUuid);
91
            descriptionLanguage = descriptionLanguage == null? Language.UNKNOWN_LANGUAGE(): descriptionLanguage;
92
            media.putDescription(descriptionLanguage, description);
93
        }
94

    
95
        //title
96
        String title = record.get(COL_TITLE);
97
        if (isBlank(title)){
98
            title = makeTitle(state, taxon, line);
99
        }
100
        if (isNotBlank(title)){
101
            UUID titleLanguageUuid = state.getConfig().getTitleLanguageUuid();
102
            Language titleLanguage = getLanguage(state, titleLanguageUuid);
103
            titleLanguage = titleLanguage == null? Language.UNKNOWN_LANGUAGE(): titleLanguage;
104
            media.putTitle(titleLanguage, title);
105
        }
106

    
107
        //copyright
108
        String copyright = record.get(COL_COPYRIGHT);
109
        if (isNotBlank(copyright)){
110
            AgentBase<?> agent = makePerson(state, copyright, line);
111
            Rights right = Rights.NewInstance(RightsType.COPYRIGHT(), agent);
112
            right = state.getDeduplicationHelper().getExistingCopyright(right);
113
            media.addRights(right);
114
        }
115

    
116
        //artist
117
        String artistStr = record.get(COL_ARTIST);
118
        if (isNotBlank(artistStr)){
119
            AgentBase<?> artist = makePerson(state, artistStr, line);
120
            media.setArtist(artist);
121
        }
122

    
123
        //date
124
        String dateStr = record.get(COL_DATE);
125
        if (isNotBlank(dateStr)){
126
            TimePeriod timePeriod = TimePeriodParser.parseString(dateStr);
127
            if (timePeriod.getFreeText() !=  null){
128
                String message = "Date could not be parsed: %s";
129
                message = String.format(message, dateStr);
130
                state.getResult().addWarning(message, null, line);
131
            }
132

    
133
            media.setMediaCreated(timePeriod);
134
        }
135

    
136
        //URLs
137
        List<URI> uris = getUrls(state, line);
138
        for (URI uri : uris){
139
            handleUri(state, uri, media, line);
140
        }
141

    
142

    
143
//        for (URI baseUrl : state.getConfig().getBaseUrls()){
144
//            if (!baseUrl.toString().endsWith("/")){
145
//                baseUrl = URI.create(baseUrl.toString() +  "/"); //is this always correct?
146
//            }
147
//            String url = baseUrl + fileName;
148
//            readImage
149
//        }
150

    
151
        //source
152
        String id = null;
153
        String idNamespace = null;
154
        Reference reference = getSourceReference(state);
155
        media.addImportSource(id, idNamespace, reference, linePure);
156

    
157
        if (taxon == null){
158
            return;
159
        }
160

    
161
        String taxonTitle = taxon.getName() == null ? taxon.getTitleCache() :
162
            isBlank(taxon.getName().getNameCache()) ? taxon.getName().getTitleCache():
163
                taxon.getName().getNameCache();
164
        TaxonDescription taxonDescription = taxon.getOrCreateImageGallery(taxonTitle);
165
        TextData textData = taxonDescription.getOrCreateImageTextData();
166
        textData.addMedia(media);
167
    }
168

    
169
    private String makeTitle(MediaExcelImportState state, Taxon taxon, String line) {
170
        MediaTitleEnum mediaTitleType = state.getConfig().getMediaTitle();
171
        if (mediaTitleType == null || mediaTitleType == MediaTitleEnum.NONE){
172
            return null;
173
        }else if(mediaTitleType == MediaTitleEnum.FILE_NAME){
174
            URI source = state.getConfig().getSource();
175
            if (source != null){
176
                String result = source.toString();
177
                while (result.endsWith("/")){
178
                    result = result.substring(0, result.length() - 1);
179
                }
180
                while (result.contains("/")){
181
                    result = result.substring(result.lastIndexOf("/"));
182
                }
183
                return result;
184
            }else{
185
               mediaTitleType = MediaTitleEnum.NAME_TITLE_CACHE;
186
            }
187
        }
188
        if (taxon == null){
189
            return null;
190
        }
191
        if (taxon.getName() == null || mediaTitleType == MediaTitleEnum.TAXON_TITLE_CACHE){
192
            return taxon.getTitleCache();
193
        }else{
194
            TaxonName name = taxon.getName();
195
            if (mediaTitleType == MediaTitleEnum.NAME_TITLE_CACHE || isBlank(name.getNameCache())){
196
                return name.getTitleCache();
197
            }else{
198
                return name.getNameCache();
199
            }
200
        }
201
    }
202

    
203
    private DateTime toDateTime(MediaExcelImportState state, Partial partial, String dateStr, String line) {
204
        if (partial == null){
205
            return null;
206
        }
207
        List<DateTimeFieldType> typeList = Arrays.asList(partial.getFieldTypes());
208
        if ( typeList.contains(DateTimeFieldType.year())
209
                && typeList.contains(DateTimeFieldType.monthOfYear())
210
                && typeList.contains(DateTimeFieldType.dayOfMonth())
211
                ){
212
            DateTime result = partial.toDateTime(DateTime.now());
213
            return result;
214
        }else{
215
            String message = "Date time does not include year, month and day information. Currently all these 3 parts are required: %s";
216
            message = String.format(message, dateStr);
217
            state.getResult().addWarning(message, null, line);
218
            return null;
219
        }
220
    }
221

    
222
    private void handleUri(MediaExcelImportState state, URI uri, Media media, String line) {
223
            CdmImageInfo cdmImageInfo = null;
224
            try {
225
                if (state.getConfig().isReadMediaData()){
226
                    cdmImageInfo = getMediaInfoFactory().cdmImageInfo(uri, false);
227
                }
228
            } catch (Exception e) {
229
                String message = "An error occurred when trying to read image meta data for %s. Image was created but without metadata.";
230
                message = String.format(message, uri.toString());
231
                state.getResult().addException(e, message, null, line);
232
            }
233
            ImageFile imageFile = ImageFile.NewInstance(uri, null, cdmImageInfo);
234

    
235
            MediaRepresentation representation = MediaRepresentation.NewInstance();
236

    
237
            if(cdmImageInfo != null){
238
                representation.setMimeType(cdmImageInfo.getMimeType());
239
                representation.setSuffix(cdmImageInfo.getSuffix());
240
            }
241
            representation.addRepresentationPart(imageFile);
242
            media.addRepresentation(representation);
243
    }
244

    
245
    private List<URI> getUrls(MediaExcelImportState state, String line) {
246
        List<URI> list = new ArrayList<>();
247
        Map<String, String> record = state.getOriginalRecord();
248
        for (String str : record.keySet()){
249
            if (str.equals("url") || str.matches("url_size\\d+") ){
250
                String url = record.get(str);
251
                try {
252
                    url = url.replace(" ", "%20");  //replace whitespace
253
                    URI uri = URI.create(url);
254
                    list.add(uri);
255
                } catch (Exception e) {
256
                    String msg = "Incorrect url " + url;
257
                    state.getResult().addError(msg, e, null, line);
258
                }
259
            }
260
        }
261

    
262
        return list;
263
    }
264

    
265
    private Person makePerson(MediaExcelImportState state, String artist, String line) {
266
        Person person = Person.NewInstance();
267
        artist = artist.trim();
268

    
269
        String regExAbbrev = "((?:[A-Z]\\. ?)+)([A-Z][a-z\\-\u00E4\u00F6\u00FC]+)";
270
        Matcher matcherAbbrev = Pattern.compile(regExAbbrev).matcher(artist);
271

    
272
        String regExFull = "([A-Z][a-z\\-\u00E4\u00F6\u00FC]+\\s)([A-Z][a-z\\-\u00E4\u00F6\u00FC]+)";
273
        Matcher matcherFull = Pattern.compile(regExFull).matcher(artist);
274

    
275
        if (matcherAbbrev.matches()){
276
            person.setGivenName(matcherAbbrev.group(1).trim());
277
            person.setFamilyName(matcherAbbrev.group(2).trim());
278
        }else if (matcherFull.matches()){
279
            person.setGivenName(matcherFull.group(1).trim());
280
            person.setFamilyName(matcherFull.group(2).trim());
281
        }else{
282
            person.setTitleCache(artist, true);
283
            String message = "A name of a person can not be atomized: %s";
284
            message = String.format(message, artist);
285
            state.getResult().addWarning(message, null, line);
286

    
287
        }
288

    
289
        Person result = state.getDeduplicationHelper().getExistingAuthor(person);
290
        return result;
291
    }
292

    
293
    @Override
294
    protected void secondPass(MediaExcelImportState state) {
295
        //not in use
296
    }
297

    
298
    @Override
299
    protected boolean isIgnore(MediaExcelImportState state) {
300
        return false;
301
    }
302
}
(1-1/4)