2 * Copyright (C) 2020 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.cdm
.api
.service
.media
;
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
;
18 import org
.apache
.log4j
.Logger
;
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
;
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()}).
32 * These volatile {@link MediaRepresentation MediaRepresentations} objects must not be persisted!
34 * @author a.kohlbecker
37 public class MediaUriTransformationProcessor
{
39 private static final Logger logger
= Logger
.getLogger(MediaUriTransformationProcessor
.class);
41 private List
<MediaUriTransformation
> transformations
= new ArrayList
<>();
43 public void add(MediaUriTransformation transformation
) {
44 transformations
.add(transformation
);
47 public void addAll(Collection
<MediaUriTransformation
> trans
) {
48 transformations
.addAll(trans
);
51 public List
<URI
> applyTo(URI uri
) {
53 logger
.debug("original: " + uri
.toString());
54 String pathQueryFragment
= buildPathQueryFragment(uri
);
56 List
<URI
> newUris
= new ArrayList
<>();
57 for (MediaUriTransformation transformation
: transformations
) {
60 URI newUri
= uriTransformation(uri
, pathQueryFragment
, transformation
);
62 } catch (URISyntaxException e
) {
70 protected URI
uriTransformation(URI uri
, String pathQueryFragment
, MediaUriTransformation replacement
)
71 throws URISyntaxException
{
73 String newScheme
= uri
.getScheme();
74 String newHost
= uri
.getHost();
75 int newPort
= uri
.getPort();
76 String newPathQueryFragment
= pathQueryFragment
;
78 boolean isMatch
= true;
80 if (replacement
.getScheme() != null) {
81 Matcher m
= replacement
.getScheme().searchPattern().matcher(newScheme
);
83 newScheme
= m
.replaceAll(replacement
.getScheme().getReplace());
85 if (replacement
.getHost() != null) {
86 Matcher m
= replacement
.getHost().searchPattern().matcher(newHost
);
88 newHost
= m
.replaceAll(replacement
.getHost().getReplace());
92 if (replacement
.getPathQueryFragment() != null) {
93 Matcher m
= replacement
.getPathQueryFragment().searchPattern().matcher(newPathQueryFragment
);
95 newPathQueryFragment
= m
.replaceAll(replacement
.getPathQueryFragment().getReplace());
99 String newURIString
= newScheme
+ "://" + newHost
+ (newPort
> 0 ?
":" + String
.valueOf(newPort
) : "")
100 + newPathQueryFragment
;
102 URI newUri
= new URI(newURIString
);
103 logger
.debug("transformed: " + newUri
.toString());
110 protected String
buildPathQueryFragment(URI uri
) {
111 String pathQueryFragment
= uri
.getPath();
112 if (uri
.getQuery() != null) {
113 pathQueryFragment
+= "?" + uri
.getQuery();
115 if (uri
.getFragment() != null) {
116 pathQueryFragment
+= "#" + uri
.getFragment();
118 return pathQueryFragment
;
122 public List
<MediaRepresentation
> makeNewMediaRepresentationsFor(URI uri
) {
124 List
<MediaRepresentation
> repr
= new ArrayList
<>();
126 String pathQueryFragment
= buildPathQueryFragment(uri
);
128 for (MediaUriTransformation transformation
: transformations
) {
131 URI newUri
= uriTransformation(uri
, pathQueryFragment
, transformation
);
132 MediaRepresentation mRepresentation
= MediaRepresentation
.NewInstance(transformation
.getMimeType(),
134 MediaRepresentationPart part
;
135 if (transformation
.getMimeType() != null && transformation
.getMimeType().startsWith("image/")) {
136 part
= ImageFile
.NewInstance(newUri
, null, transformation
.getHeight(), transformation
.getWidth());
138 part
= MediaRepresentationPart
.NewInstance(newUri
, null);
140 mRepresentation
.addRepresentationPart(part
);
141 repr
.add(mRepresentation
);
143 } catch (URISyntaxException e
) {
151 public List
<MediaRepresentation
> makeNewMediaRepresentationsFor(MediaRepresentationPart part
) {
153 List
<MediaRepresentation
> repr
= new ArrayList
<>();
155 String pathQueryFragment
= buildPathQueryFragment(part
.getUri());
157 for (MediaUriTransformation transformation
: transformations
) {
160 URI newUri
= uriTransformation(part
.getUri(), pathQueryFragment
, transformation
);
161 if (newUri
.equals(part
.getUri())) {
162 // transformation did not apply
165 MediaRepresentation mRepresentation
= MediaRepresentation
.NewInstance(transformation
.getMimeType(),
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
);
175 newPart
= ImageFile
.NewInstance(newUri
, null, transformation
.getHeight(),
176 transformation
.getWidth());
179 newPart
= MediaRepresentationPart
.NewInstance(newUri
, null);
181 mRepresentation
.addRepresentationPart(newPart
);
182 repr
.add(mRepresentation
);
184 } catch (URISyntaxException e
) {
196 * @param originalWidth
197 * @param originalHeight
198 * @param calculateMaxExtend
201 protected Point
calculateTargetSize(MediaUriTransformation trans
, Integer originalWidth
, Integer originalHeight
) {
203 if (trans
.getWidth() == null && trans
.getHeight() == null) {
205 } else if (originalWidth
== null || originalHeight
== null) {
206 return new Point(trans
.getWidth(), trans
.getHeight());
208 if(trans
.getHeight() != null && trans
.getWidth() != null && !trans
.isMaxExtend()) {
210 return new Point(trans
.getWidth(), trans
.getHeight());
213 float originalAspectRatio
= ((float) originalWidth
/ (float) originalHeight
);
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
));
220 return new Point(Math
.round(trans
.getHeight() * originalAspectRatio
), trans
.getHeight());