Project

General

Profile

Download (8.32 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2020 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.awt.Point;
12
import java.net.URI;
13
import java.net.URISyntaxException;
14
import java.util.ArrayList;
15
import java.util.Collection;
16
import java.util.List;
17
import java.util.regex.Matcher;
18

    
19
import org.apache.log4j.Logger;
20

    
21
import eu.etaxonomy.cdm.model.media.ImageFile;
22
import eu.etaxonomy.cdm.model.media.MediaRepresentation;
23
import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
24
import eu.etaxonomy.cdm.model.metadata.PreferencePredicate;
25

    
26
/**
27
 * Creates new purely volatile {@link MediaRepresentation MediaRepresentations} objects based on
28
 * a list of {@link MediaUriTransformation} rules. These rules are usually stored in the
29
 * per data base {@link PreferencePredicate.MediaRepresentationTransformations MediaRepresentationTransformations} property
30
 * (See also {@link MediaToolbox#readTransformations()}).
31
 * <p>
32
 * These volatile {@link MediaRepresentation MediaRepresentations} objects must not be persisted!
33
 *
34
 * @author a.kohlbecker
35
 * @since Jul 8, 2020
36
 */
37
public class MediaUriTransformationProcessor {
38

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

    
41
    private List<MediaUriTransformation> transformations = new ArrayList<>();
42

    
43
    public void add(MediaUriTransformation transformation) {
44
        transformations.add(transformation);
45
    }
46

    
47
    public void addAll(Collection<MediaUriTransformation> trans) {
48
        transformations.addAll(trans);
49
    }
50

    
51
    public List<URI> applyTo(URI uri) {
52

    
53
        logger.debug("original:    " + uri.toString());
54
        String pathQueryFragment = buildPathQueryFragment(uri);
55

    
56
        List<URI> newUris = new ArrayList<>();
57
        for (MediaUriTransformation transformation : transformations) {
58

    
59
            try {
60
                URI newUri = uriTransformation(uri, pathQueryFragment, transformation);
61
                newUris.add(newUri);
62
            } catch (URISyntaxException e) {
63
                logger.error(e);
64
            }
65
        }
66

    
67
        return newUris;
68
    }
69

    
70
    protected URI uriTransformation(URI uri, String pathQueryFragment, MediaUriTransformation replacement)
71
            throws URISyntaxException {
72

    
73
        String newScheme = uri.getScheme();
74
        String newHost = uri.getHost();
75
        int newPort = uri.getPort();
76
        String newPathQueryFragment = pathQueryFragment;
77

    
78
        boolean isMatch = true;
79
        // replace the parts
80
        if (replacement.getScheme() != null) {
81
            Matcher m = replacement.getScheme().searchPattern().matcher(newScheme);
82
            isMatch &= m.find();
83
            newScheme = m.replaceAll(replacement.getScheme().getReplace());
84
        }
85
        if (replacement.getHost() != null) {
86
            Matcher m = replacement.getHost().searchPattern().matcher(newHost);
87
            isMatch &= m.find();
88
            newHost = m.replaceAll(replacement.getHost().getReplace());
89
        }
90
        // TODO port
91

    
92
        if (replacement.getPathQueryFragment() != null) {
93
            Matcher m = replacement.getPathQueryFragment().searchPattern().matcher(newPathQueryFragment);
94
            isMatch &= m.find();
95
            newPathQueryFragment = m.replaceAll(replacement.getPathQueryFragment().getReplace());
96
        }
97
        if (isMatch) {
98
            // recombine
99
            String newURIString = newScheme + "://" + newHost + (newPort > 0 ? ":" + String.valueOf(newPort) : "")
100
                    + newPathQueryFragment;
101

    
102
            URI newUri = new URI(newURIString);
103
            logger.debug("transformed: " + newUri.toString());
104
            return newUri;
105
        } else {
106
            return uri;
107
        }
108
    }
109

    
110
    protected String buildPathQueryFragment(URI uri) {
111
        String pathQueryFragment = uri.getPath();
112
        if (uri.getQuery() != null) {
113
            pathQueryFragment += "?" + uri.getQuery();
114
        }
115
        if (uri.getFragment() != null) {
116
            pathQueryFragment += "#" + uri.getFragment();
117
        }
118
        return pathQueryFragment;
119
    }
120

    
121
    @Deprecated
122
    public List<MediaRepresentation> makeNewMediaRepresentationsFor(URI uri) {
123

    
124
        List<MediaRepresentation> repr = new ArrayList<>();
125

    
126
        String pathQueryFragment = buildPathQueryFragment(uri);
127

    
128
        for (MediaUriTransformation transformation : transformations) {
129

    
130
            try {
131
                URI newUri = uriTransformation(uri, pathQueryFragment, transformation);
132
                MediaRepresentation mRepresentation = MediaRepresentation.NewInstance(transformation.getMimeType(),
133
                        null);
134
                MediaRepresentationPart part;
135
                if (transformation.getMimeType() != null && transformation.getMimeType().startsWith("image/")) {
136
                    part = ImageFile.NewInstance(newUri, null, transformation.getHeight(), transformation.getWidth());
137
                } else {
138
                    part = MediaRepresentationPart.NewInstance(newUri, null);
139
                }
140
                mRepresentation.addRepresentationPart(part);
141
                repr.add(mRepresentation);
142

    
143
            } catch (URISyntaxException e) {
144
                logger.error(e);
145
            }
146
        }
147

    
148
        return repr;
149
    }
150

    
151
    public List<MediaRepresentation> makeNewMediaRepresentationsFor(MediaRepresentationPart part) {
152

    
153
        List<MediaRepresentation> repr = new ArrayList<>();
154

    
155
        String pathQueryFragment = buildPathQueryFragment(part.getUri());
156

    
157
        for (MediaUriTransformation transformation : transformations) {
158

    
159
            try {
160
                URI newUri = uriTransformation(part.getUri(), pathQueryFragment, transformation);
161
                if (newUri.equals(part.getUri())) {
162
                    // transformation did not apply
163
                    continue;
164
                }
165
                MediaRepresentation mRepresentation = MediaRepresentation.NewInstance(transformation.getMimeType(),
166
                        null);
167
                MediaRepresentationPart newPart;
168
                if (transformation.getMimeType() != null && transformation.getMimeType().startsWith("image/")) {
169
                    if (part instanceof ImageFile) {
170
                        ImageFile originalImageFile = (ImageFile) part;
171
                        Point newSize = calculateTargetSize(transformation, originalImageFile.getWidth(),
172
                                originalImageFile.getHeight());
173
                        newPart = ImageFile.NewInstance(newUri, null, newSize.y, newSize.x);
174
                    } else {
175
                        newPart = ImageFile.NewInstance(newUri, null, transformation.getHeight(),
176
                                transformation.getWidth());
177
                    }
178
                } else {
179
                    newPart = MediaRepresentationPart.NewInstance(newUri, null);
180
                }
181
                mRepresentation.addRepresentationPart(newPart);
182
                repr.add(mRepresentation);
183

    
184
            } catch (URISyntaxException e) {
185
                logger.error(e);
186
            }
187
        }
188

    
189
        return repr;
190
    }
191

    
192
    protected Point calculateTargetSize(MediaUriTransformation trans, Integer originalWidth, Integer originalHeight) {
193

    
194
        if (trans.getWidth() == null && trans.getHeight() == null) {
195
            return null;
196
        } else if (originalWidth == null || originalHeight == null) {
197
            return new Point(trans.getWidth(), trans.getHeight());
198
        } else {
199
            if(trans.getHeight() != null && trans.getWidth() != null && !trans.getHeight().equals(trans.getWidth())) {
200
                return new Point(trans.getWidth(), trans.getHeight());
201
            } else {
202
                // calculate
203
                float originalAspectRatio = ((float) originalWidth / (float) originalHeight);
204

    
205
                boolean widthIsLimiting = trans.getHeight() == null ||
206
                        trans.getWidth() != null && trans.getHeight() * originalAspectRatio > trans.getWidth() ;
207
                if (widthIsLimiting){
208
                    return new Point(trans.getWidth(), Math.round(trans.getWidth() / originalAspectRatio ));
209
                } else {
210
                    return new Point(Math.round(trans.getHeight() * originalAspectRatio), trans.getHeight());
211
                }
212
            }
213
        }
214
    }
215
}
(3-3/4)