Skip to contentPackage: RegexTreeMap
RegexTreeMap
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.impl.util;
28:
29: import javax.annotation.Nonnull;
30: import java.util.TreeMap;
31: import java.util.regex.Pattern;
32:
33: /***********************************************************************************************************************
34: *
35: * A specialization of {@link TreeMap} that is capable to deal with regular expressions. When a value must be bound to
36: * a regular expression, use the method {@link #putRegex(java.lang.String, java.lang.Object)} instead of
37: * {@link #put(java.lang.String, java.lang.Object)}.
38: *
39: * @author Fabrizio Giudici
40: *
41: **********************************************************************************************************************/
42: public class RegexTreeMap<Type> extends TreeMap<String, Type>
43: {
44: private static final long serialVersionUID = 576876596539246L;
45:
46: @Nonnull
47: public static String escape (@Nonnull final String string)
48: {
49: final var builder = new StringBuilder();
50:
51:• for (var i = 0; i < string.length(); i++)
52: {
53: final var c = string.charAt(i);
54:
55:• if ("[\\^$.|?*+()".contains("" + c))
56: {
57: builder.append('\\');
58: }
59:
60: builder.append(c);
61: }
62:
63: return builder.toString();
64: }
65:
66: @Override
67: public Type put (@Nonnull final String string, final Type value)
68: {
69: return super.put(Pattern.quote(string), value);
70: }
71:
72: public Type putRegex (@Nonnull final String regex, final Type value)
73: {
74: return super.put(regex, value);
75: }
76:
77: @Override
78: public Type get (@Nonnull final Object value)
79: {
80: final var stringValue = (String)value;
81: var result = super.get(Pattern.quote(stringValue)); // first try a direct match that is fast
82: var matchLength = 0;
83:
84:• if (result == null) // otherwise returns the longest match
85: {
86:• for (final var entry : entrySet())
87: {
88: final var regex = entry.getKey();
89:
90:• if (stringValue.matches(regex) && (regex.length() > matchLength))
91: {
92: result = entry.getValue();
93: matchLength = regex.length();
94: }
95: }
96: }
97:
98: return result;
99: }
100: }