ref #9607 removing obsolete methods
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / media / MediaUriTransformationProcessor.java
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.URISyntaxException;
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.List;
16 import java.util.regex.Matcher;
17
18 import org.apache.log4j.Logger;
19
20 import eu.etaxonomy.cdm.common.URI;
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 /**
193 *
194 * @param trans
195 * The transfomation
196 * @param originalWidth
197 * @param originalHeight
198 * @param calculateMaxExtend
199 * @return
200 */
201 protected Point calculateTargetSize(MediaUriTransformation trans, Integer originalWidth, Integer originalHeight) {
202
203 if (trans.getWidth() == null && trans.getHeight() == null) {
204 return null;
205 } else if (originalWidth == null || originalHeight == null) {
206 return new Point(trans.getWidth(), trans.getHeight());
207 } else {
208 if(trans.getHeight() != null && trans.getWidth() != null && !trans.isMaxExtend()) {
209 // CROP
210 return new Point(trans.getWidth(), trans.getHeight());
211 } else {
212 // MAX EXTEND
213 float originalAspectRatio = ((float) originalWidth / (float) originalHeight);
214
215 boolean widthIsLimiting = trans.getHeight() == null ||
216 trans.getWidth() != null && trans.getHeight() * originalAspectRatio > trans.getWidth();
217 if (widthIsLimiting){
218 return new Point(trans.getWidth(), Math.round(trans.getWidth() / originalAspectRatio ));
219 } else {
220 return new Point(Math.round(trans.getHeight() * originalAspectRatio), trans.getHeight());
221 }
222 }
223 }
224 }
225 }