2 * Copyright (c) 2018 Red Hat, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.aaa.web;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.collect.ImmutableList;
13 import com.google.common.collect.ImmutableMap;
14 import java.util.List;
16 import javax.servlet.Filter;
17 import org.eclipse.jdt.annotation.NonNull;
20 * Details about a {@link Filter}.
22 * @author Michael Vorburger.ch
24 public interface FilterDetails {
26 * Get a {@link Filter} instance.
28 * @return {@link Filter} instance
30 @NonNull Filter filter();
35 * @return {@link String}
37 @NonNull String name();
40 * Get list of Filter URL patterns. These patterns control where filter is applied.
43 * Restrictions to URLs and how it should look like are next:
45 * <li>A string beginning with a ‘ / ’ character and ending with a ‘ /*’ suffix is used for path mapping.</li>
46 * <li>A string beginning with a ‘ *. ’ prefix is used as an extension mapping.</li>
47 * <li>The empty string ("") is a special URL pattern that exactly maps to the application's context root, i.e.,
48 * requests of the form {@code http://host:port/context-root/}. In this case the path info is ’ / ’ and the
49 * servlet path and context path is empty string (““).</li>
50 * <li>A string containing only the ’ / ’ character indicates the "default" servlet of the application. In this
51 * case the servlet path is the request URI minus the context path and the path info is null.</li>
52 * <li>All other strings are used for exact matches only.</li>
55 * @return {@link List} of Filter URL patterns
56 * @see "Java Servlet Specification Version 3.1, Section 12.2 Specification of Mappings"
58 @NonNull List<String> urlPatterns();
61 * Get Filter initial parameters.
63 * @return {@link Map} that contains initial parameters
65 @NonNull Map<String, String> initParams();
68 * Get indication whether {@link #filter()} supports asynchronous processing.
70 * @return {@code true} if the filter supports asynchronous processing
71 * @see "Java Servlet Specification Version 3.1, Section 2.3.3.3 Asynchronous Processing"
73 boolean asyncSupported();
76 * Create a builder for {@link FilterDetails}.
78 * @return {@link Builder} builder instance
80 static @NonNull Builder builder() {
85 * Builds instances of type {@link FilterDetails FilterDetails}. Initialize attributes and then invoke the
86 * {@link #build()} method to create an immutable instance.
88 * <p><em>{@code FilterDetails.Builder} is not thread-safe and generally should not be stored in a field or
89 * collection, but instead used immediately to create instances.</em>
92 private record ImmutableFilterDetails(Filter filter, String name, ImmutableList<String> urlPatterns,
93 ImmutableMap<String, String> initParams, boolean asyncSupported) implements FilterDetails {
94 ImmutableFilterDetails {
95 if (urlPatterns.isEmpty()) {
96 throw new IllegalStateException("No urlPattern specified");
101 private final ImmutableMap.Builder<String, String> initParams = ImmutableMap.builder();
102 private final ImmutableList.Builder<String> urlPatterns = ImmutableList.builder();
103 private Filter filter;
105 private boolean asyncSupported;
112 * Initializes the value for the {@link FilterDetails#filter() filter} attribute.
114 * @param filter The value for filter
115 * @return {@code this} builder for use in a chained invocation
117 @SuppressWarnings("checkstyle:hiddenField")
118 public @NonNull Builder filter(final Filter filter) {
119 this.filter = requireNonNull(filter);
124 * Initializes the value for the {@link FilterDetails#name() name} attribute.
126 * <p><em>If not set, this attribute will have a value corresponding to {@code filter().getClass().getName()}.
129 * @param name The value for name
130 * @return {@code this} builder for use in a chained invocation
131 * @throws NullPointerException if {code name} is {@code null}
133 @SuppressWarnings("checkstyle:hiddenField")
134 public @NonNull Builder name(final String name) {
135 this.name = requireNonNull(name);
140 * Adds one element to {@link FilterDetails#urlPatterns() urlPatterns} list.
142 * @param urlPattern A urlPatterns element
143 * @return {@code this} builder for use in a chained invocation
144 * @throws NullPointerException if {code urlPattern} is {@code null}
145 * @throws IllegalArgumentException if {@code urlPattern} does not meet specification criteria
147 public @NonNull Builder addUrlPattern(final String urlPattern) {
148 urlPatterns.add(ServletSpec.requireMappingSpec(urlPattern));
153 * Put one entry to the {@link FilterDetails#initParams() initParams} map.
155 * @param key The key in the initParams map
156 * @param value The associated value in the initParams map
157 * @return {@code this} builder for use in a chained invocation
158 * @throws NullPointerException if any argument is {@code null}
160 public @NonNull Builder putInitParam(final String key, final String value) {
161 initParams.put(key, value);
166 * Initializes the value for the {@link FilterDetails#asyncSupported() asyncSupported} attribute.
168 * <p><em>If not set, this attribute will have a default value of {@code false}.</em>
170 * @param asyncSupported The value for asyncSupported
171 * @return {@code this} builder for use in a chained invocation
173 @SuppressWarnings("checkstyle:hiddenField")
174 public @NonNull Builder asyncSupported(final boolean asyncSupported) {
175 this.asyncSupported = asyncSupported;
180 * Builds a new {@link FilterDetails FilterDetails}.
182 * @return An immutable instance of FilterDetails
183 * @throws IllegalStateException if any required attributes are missing
185 public @NonNull FilterDetails build() {
186 if (filter == null) {
187 throw new IllegalStateException("No filter specified");
189 return new ImmutableFilterDetails(filter, name != null ? name : filter.getClass().getName(),
190 urlPatterns.build(), initParams.build(), asyncSupported);