Project

General

Profile

Download (6.36 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2021 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.api.service.media;
10

    
11
import java.io.IOException;
12
import java.io.InputStream;
13

    
14
import org.apache.commons.imaging.ImageInfo;
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.commons.lang3.StringUtils;
21
import org.apache.http.HttpException;
22
import org.apache.http.client.ClientProtocolException;
23
import org.apache.log4j.Logger;
24

    
25
import eu.etaxonomy.cdm.common.CdmUtils;
26
import eu.etaxonomy.cdm.common.URI;
27
import eu.etaxonomy.cdm.common.UriUtils;
28
import eu.etaxonomy.cdm.common.media.CdmImageInfo;
29

    
30
/**
31
 *  TODO make use of timeOut ?
32
 *
33
 * @author a.kohlbecker
34
 * @since May 6, 2021
35
 */
36
public class MediaMedadataFileReader {
37

    
38

    
39
    private static Logger logger = Logger.getLogger(MediaMedadataFileReader.class);
40

    
41
    private CdmImageInfo cdmImageInfo;
42

    
43
    public static final Integer IMAGE_READ_TIMEOUT = 3000; // ms
44

    
45
    private Integer timeOut = IMAGE_READ_TIMEOUT; // setting default
46

    
47
    public MediaMedadataFileReader(CdmImageInfo cdmImageInfo) {
48
        this.cdmImageInfo = cdmImageInfo;
49
    }
50

    
51
    public MediaMedadataFileReader(URI uri) {
52
        this.cdmImageInfo = new CdmImageInfo(uri);
53
    }
54

    
55
    /**
56
     * Reads the image info (width, height, bitPerPixel, metadata, format, mime type)
57
     */
58
    public MediaMedadataFileReader readImageInfo() throws IOException, HttpException{
59

    
60
        InputStream inputStream;
61
        try {
62
            inputStream = UriUtils.getInputStream(cdmImageInfo.getUri());
63
            ImageInfo imageInfo = Imaging.getImageInfo(inputStream, null);
64

    
65
            cdmImageInfo.setFormatName(imageInfo.getFormatName());
66
            cdmImageInfo.setMimeType(imageInfo.getMimeType());
67
            cdmImageInfo.setWidth(imageInfo.getWidth());
68
            cdmImageInfo.setHeight(imageInfo.getHeight());
69
            cdmImageInfo.setBitPerPixel(imageInfo.getBitsPerPixel());
70
            inputStream.close();
71

    
72
        } catch (ImageReadException e) {
73
            logger.error("Could not read: " + cdmImageInfo.getUri() + ". " + e.getMessage());
74
            throw new IOException(e);
75
        }
76

    
77
        return this;
78
    }
79

    
80
    public MediaMedadataFileReader readMetaData() throws IOException, HttpException {
81

    
82
        ImageMetadata mediaData = null;
83
        try {
84
            InputStream inputStream = UriUtils.getInputStream(cdmImageInfo.getUri());
85
            mediaData = Imaging.getMetadata(inputStream, null);
86
        }catch (ImageReadException e) {
87
            logger.error("Could not read: " + cdmImageInfo.getUri() + ". " + e.getMessage());
88
            //throw new IOException(e);
89
        }
90

    
91
        if(mediaData != null) {
92
            for (ImageMetadataItem imItem : mediaData.getItems()){
93
                if (imItem instanceof GenericImageMetadataItem){
94
                    GenericImageMetadataItem item = (GenericImageMetadataItem)imItem;
95
                    if ("Keywords".equals(item.getKeyword())){
96
                        String value = text(item);
97
                        String[] splits = value.split(":");
98
                        if (splits.length == 2){
99
                            //convention used e.g. for Flora of cyprus (#9137)
100
                            cdmImageInfo.getMetaData().put(splits[0].trim(), splits[1].trim());
101
                        }else{
102
                            cdmImageInfo.getMetaData().put(
103
                                    item.getKeyword(),
104
                                    CdmUtils.concat("; ", cdmImageInfo.getMetaData().get(item.getKeyword()), value)
105
                                    );
106
                        }
107
                    }else if (item.getKeyword().contains("/")){
108
                        //TODO: not sure where this syntax is used originally
109
                        String key = item.getKeyword();
110
                        //key.replace("/", "");
111
                        int index = key.indexOf("/");
112
                        key = key.substring(0, index);
113
                        cdmImageInfo.getMetaData().put(key, text(item));
114
                    }else{
115
                        cdmImageInfo.getMetaData().put(item.getKeyword(), text(item));
116
                    }
117
                }
118
            }
119
        }
120

    
121
        return this;
122
    }
123

    
124
    /**
125
     * Reads the size of the image defined by the {@link #imageUri} in bytes
126
     */
127
    public MediaMedadataFileReader readImageLength() throws ClientProtocolException, IOException, HttpException{
128
        try {
129
            long length = UriUtils.getResourceLength(cdmImageInfo.getUri(), null);
130
            cdmImageInfo.setLength(length);
131
        } catch (HttpException e) {
132
            if (e.getMessage().equals("Could not retrieve Content-Length")){
133
                InputStream inputStream = UriUtils.getInputStream(cdmImageInfo.getUri());
134
                int n = 0;
135
                while(inputStream.read() != -1){
136
                    n++;
137
                }
138
                inputStream.close();
139
                logger.info("Content-Length not available in http header. Image size computed via input stream size: " + cdmImageInfo.getUri());
140
                cdmImageInfo.setLength(n);
141
            }else{
142
                throw e;
143
            }
144
        }
145
        return this;
146
    }
147

    
148
    public MediaMedadataFileReader readSuffix(){
149
        String path = cdmImageInfo.getUri().getPath();
150
        String suffix = path.substring(StringUtils.lastIndexOf(path, '.') + 1);
151
        cdmImageInfo.setSuffix(suffix);
152
        return this;
153
    }
154

    
155
    public CdmImageInfo getCdmImageInfo() {
156
        return cdmImageInfo;
157
    }
158

    
159
    /**
160
     * Wrapper for the Item.getText() method which applies cleaning of the text representation.
161
     * <ol>
162
     * <li>Strings are surrounded by single quotes, these must be removed</li>
163
     * </ol>
164
     * @param item
165
     */
166
    private String text(GenericImageMetadataItem item) {
167
        String  text = item.getText();
168
        if(text.startsWith("'") && text.endsWith("'")) {
169
            text = text.substring(1 , text.length() - 1);
170
        }
171
        return text;
172
    }
173

    
174

    
175

    
176
}
(3-3/6)