001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.protocol.http.servlet;
018
019import java.util.List;
020import java.util.regex.Pattern;
021import java.util.regex.PatternSyntaxException;
022
023import jakarta.servlet.http.HttpServletRequest;
024
025import org.apache.wicket.util.lang.Generics;
026import org.apache.wicket.util.string.Strings;
027
028/**
029 * A factory of {@link HttpServletRequest} wrappers.
030 * 
031 * @author Juergen Donnerstag
032 */
033public abstract class AbstractRequestWrapperFactory
034{
035        /**
036         * {@link Pattern} for a comma delimited string that support whitespace characters
037         */
038        private static final Pattern commaSeparatedValuesPattern = Pattern.compile("\\s*,\\s*");
039
040        private boolean enabled = true;
041
042        /**
043         * Construct.
044         */
045        public AbstractRequestWrapperFactory()
046        {
047        }
048
049        /**
050         * 
051         * @return {@code true} if filter is enabled
052         */
053        public final boolean isEnabled()
054        {
055                return enabled;
056        }
057
058        /**
059         * Enable or disable the filter
060         * 
061         * @param enabled
062         */
063        public final void setEnabled(boolean enabled)
064        {
065                this.enabled = enabled;
066        }
067
068        /**
069         * Wrap the given request.
070         * 
071         * @param request request to wrap
072         * @return Either return the request itself, or if needed a wrapper for the request
073         */
074        public HttpServletRequest getWrapper(final HttpServletRequest request)
075        {
076                if (isEnabled() && needsWrapper(request))
077                {
078                        return newRequestWrapper(request);
079                }
080                return request;
081        }
082
083        /**
084         * @param request
085         * @return True, if a wrapper is needed
086         */
087        protected abstract boolean needsWrapper(final HttpServletRequest request);
088
089        /**
090         * @param request
091         * @return Create a wrapper for the request
092         */
093        public abstract HttpServletRequest newRequestWrapper(HttpServletRequest request);
094
095        /**
096         * Convert a given comma delimited list of regular expressions into an array of compiled
097         * {@link Pattern}
098         * 
099         * @param commaDelimitedPatterns
100         * @return array of patterns (not <code>null</code>)
101         */
102        public static Pattern[] commaDelimitedListToPatternArray(
103                final String commaDelimitedPatterns)
104        {
105                String[] patterns = commaDelimitedListToStringArray(commaDelimitedPatterns);
106                List<Pattern> patternsList = Generics.newArrayList();
107                for (String pattern : patterns)
108                {
109                        try
110                        {
111                                patternsList.add(Pattern.compile(pattern));
112                        }
113                        catch (PatternSyntaxException e)
114                        {
115                                throw new IllegalArgumentException("Illegal pattern syntax '" + pattern + "'", e);
116                        }
117                }
118                return patternsList.toArray(new Pattern[patternsList.size()]);
119        }
120
121        /**
122         * Convert a given comma delimited list of regular expressions into an array of String
123         * 
124         * @param commaDelimitedStrings
125         * @return array of patterns (non <code>null</code>)
126         */
127        public static String[] commaDelimitedListToStringArray(final String commaDelimitedStrings)
128        {
129                if (Strings.isEmpty(commaDelimitedStrings))
130                {
131                        return new String[0];
132                }
133                else
134                {
135                        return commaSeparatedValuesPattern.split(commaDelimitedStrings);
136                }
137        }
138
139        /**
140         * Convert an array of strings in a comma delimited string
141         * 
142         * @param stringList
143         * @return xxx
144         */
145        public static String listToCommaDelimitedString(final List<String> stringList)
146        {
147                return Strings.join(", ", stringList);
148        }
149
150        /**
151         * 
152         * @param str
153         * @param patterns
154         * @return Return <code>true</code> if the given <code>str</code> matches at least one of the
155         *         given <code>patterns</code>.
156         */
157        public static boolean matchesOne(final String str, final Pattern... patterns)
158        {
159                for (Pattern pattern : patterns)
160                {
161                        if (pattern.matcher(str).matches())
162                        {
163                                return true;
164                        }
165                }
166                return false;
167        }
168}