Package: DefaultMediaRequestProcessor
DefaultMediaRequestProcessor
name | instruction | branch | complexity | line | method | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
DefaultMediaRequestProcessor() |
|
|
|
|
|
||||||||||||||||||||
getDuration() |
|
|
|
|
|
||||||||||||||||||||
getUriPrefix() |
|
|
|
|
|
||||||||||||||||||||
process(Request) |
|
|
|
|
|
||||||||||||||||||||
setDuration(Duration) |
|
|
|
|
|
||||||||||||||||||||
setUriPrefix(String) |
|
|
|
|
|
||||||||||||||||||||
static {...} |
|
|
|
|
|
Coverage
1: /*
2: * #%L
3: * *********************************************************************************************************************
4: *
5: * NorthernWind - lightweight CMS
6: * http://northernwind.tidalwave.it - git clone https://bitbucket.org/tidalwave/northernwind-src.git
7: * %%
8: * Copyright (C) 2011 - 2023 Tidalwave s.a.s. (http://tidalwave.it)
9: * %%
10: * *********************************************************************************************************************
11: *
12: * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
13: * the License. You may obtain a copy of the License at
14: *
15: * http://www.apache.org/licenses/LICENSE-2.0
16: *
17: * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
18: * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
19: * specific language governing permissions and limitations under the License.
20: *
21: * *********************************************************************************************************************
22: *
23: *
24: * *********************************************************************************************************************
25: * #L%
26: */
27: package it.tidalwave.northernwind.core.model.spi;
28:
29: import javax.annotation.Nonnull;
30: import javax.inject.Inject;
31: import javax.inject.Provider;
32: import java.time.Duration;
33: import java.io.IOException;
34: import org.springframework.core.annotation.Order;
35: import it.tidalwave.util.NotFoundException;
36: import it.tidalwave.northernwind.core.model.Request;
37: import it.tidalwave.northernwind.core.model.RequestProcessor;
38: import it.tidalwave.northernwind.core.model.ResourcePath;
39: import it.tidalwave.northernwind.core.model.SiteProvider;
40: import lombok.Getter;
41: import lombok.Setter;
42: import lombok.extern.slf4j.Slf4j;
43: import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE;
44: import static it.tidalwave.northernwind.core.model.Media._Media_;
45: import static it.tidalwave.northernwind.core.model.RequestProcessor.Status.*;
46:
47: /***********************************************************************************************************************
48: *
49: * @author Fabrizio Giudici
50: *
51: **********************************************************************************************************************/
52: @Slf4j @Order(HIGHEST_PRECEDENCE+2)
53: public class DefaultMediaRequestProcessor<ResponseType> implements RequestProcessor
54: {
55: @Inject
56: private Provider<SiteProvider> siteProvider;
57:
58: @Inject
59: protected ResponseHolder<ResponseType> responseHolder;
60:
61: @Getter @Setter
62: private Duration duration = Duration.ofDays(7); // FIXME: rename to expirationDuration
63:
64: @Getter @Setter
65: private String uriPrefix = "media"; // FIXME
66:
67: @Override @Nonnull
68: public Status process (@Nonnull final Request request)
69: throws NotFoundException, IOException
70: {
71: var mediaUri = ResourcePath.of(request.getRelativeUri());
72:
73:• if (!mediaUri.startsWith(uriPrefix))
74: {
75: return CONTINUE;
76: }
77:
78: mediaUri = mediaUri.withoutLeading(); // media
79: //
80: // Media that can be served at different sizes are mapped to URLs such as:
81: //
82: // /media/stillimages/<media-id>/<size>/image.jpg
83: // /media/movies/<media-id>/<size>/movie.jpg
84: //
85: // TODO: perhaps this logic should be moved to the media finder? Such as:
86: // find(Media).withSize(1920).withRelativePath(uri).result()
87: //
88:• if (mediaUri.startsWith("stillimages") || mediaUri.startsWith("movies"))
89: {
90: //
91: // TODO: retrocompatibility with StoppingDown and Bluette
92: // http://stoppingdown.net/media/stillimages/1920/20120802-0010.jpg
93: // Should be dealt with a specific redirector in the website and removed from here.
94: //
95:• if (mediaUri.getSegmentCount() == 3)
96: {
97: final var extension = mediaUri.getExtension();
98: final var fileName = mediaUri.getTrailing(); // 20120802-0010.jpg
99: mediaUri = mediaUri.withoutTrailing();
100: final var size = mediaUri.getTrailing(); // 1920
101: mediaUri = mediaUri.withoutTrailing();
102: mediaUri = mediaUri.appendedWith(fileName.replaceAll("\\..*$", ""))
103: .appendedWith("" + size)
104: .appendedWith("image." + extension);
105: mediaUri = mediaUri.prependedWith(uriPrefix);
106: final var redirect = mediaUri.asString();
107: log.info(">>>> permanently redirecting to {}", redirect);
108: responseHolder.response().permanentRedirect(redirect).put();
109: return BREAK;
110: }
111: // END TODO
112:
113: final var extension = mediaUri.getExtension(); // jpg
114: // final String fileName = mediaUri.getTrailing(); // image.jpg
115: mediaUri = mediaUri.withoutTrailing();
116: final var size = mediaUri.getTrailing(); // 1920
117: mediaUri = mediaUri.withoutTrailing();
118: final var mediaId = mediaUri.getTrailing(); // 20120802-0010
119: mediaUri = mediaUri.withoutTrailing();
120: mediaUri = mediaUri.appendedWith(size).appendedWith(mediaId + "." + extension);
121: }
122:
123: final var media = siteProvider.get().getSite().find(_Media_).withRelativePath(mediaUri).result();
124: final var file = media.getFile();
125: log.info(">>>> serving contents of {} ...", file.getPath().asString());
126:
127: responseHolder.response().fromFile(file)
128: .withExpirationTime(duration)
129: .forRequest(request)
130: .put();
131: return BREAK;
132: }
133: }