1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.virtualuri;
35
36 import info.magnolia.cms.core.AggregationState;
37 import info.magnolia.cms.filters.AbstractMgnlFilter;
38 import info.magnolia.cms.util.RequestDispatchUtil;
39
40 import java.io.IOException;
41 import java.net.URI;
42 import java.net.URISyntaxException;
43 import java.util.Optional;
44
45 import javax.inject.Inject;
46 import javax.inject.Provider;
47 import javax.servlet.FilterChain;
48 import javax.servlet.ServletException;
49 import javax.servlet.http.HttpServletRequest;
50 import javax.servlet.http.HttpServletResponse;
51
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55
56
57
58
59
60 public class VirtualUriFilter extends AbstractMgnlFilter {
61
62 private static final Logger log = LoggerFactory.getLogger(VirtualUriFilter.class);
63
64 private VirtualUriRegistry registry;
65 private Provider<AggregationState> aggregationStateProvider;
66
67 @Inject
68 public VirtualUriFilter(VirtualUriRegistry registry, Provider<AggregationState> aggregationStateProvider) {
69 this.registry = registry;
70 this.aggregationStateProvider = aggregationStateProvider;
71 }
72
73 @Override
74 public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
75 throws IOException, ServletException {
76
77 final AggregationState aggregationState = aggregationStateProvider.get();
78 String currentUri = aggregationState.getCurrentURI();
79 String queryString = aggregationState.getQueryString();
80
81
82 final URI uri;
83 try {
84 uri = new URI(null, null, currentUri, queryString, null);
85 } catch (URISyntaxException e) {
86 log.warn("Cannot reconstruct a valid URI from the aggregation state data", e);
87 chain.doFilter(request, response);
88 return;
89 }
90
91 Optional<VirtualUriMapping.Result> mappingBestMatch = registry.getAllDefinitions().stream()
92 .map(uriMapping -> uriMapping.mapUri(uri))
93 .filter(Optional::isPresent)
94 .map(Optional::get)
95 .max(VirtualUriMapping.Result::compareTo);
96
97 if (!mappingBestMatch.isPresent()) {
98 chain.doFilter(request, response);
99 return;
100 }
101
102 VirtualUriMapping.Result result = mappingBestMatch.get();
103 String targetUri = result.getToUri();
104
105 if (response.isCommitted()) {
106 log.warn(
107 "Response is already committed, cannot apply virtual URI {} (original URI was {})",
108 targetUri,
109 request.getRequestURI());
110 chain.doFilter(request, response);
111 return;
112 }
113
114 if (RequestDispatchUtil.dispatch(targetUri, request, response)) {
115 return;
116 }
117
118 aggregationState.setCurrentURI(targetUri);
119 chain.doFilter(request, response);
120 }
121 }