io.undertow.servlet.handlers.ServletPathMatchesData Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.undertow.servlet.handlers;
import io.undertow.UndertowMessages;
import io.undertow.util.SubstringMap;
import java.util.HashMap;
import java.util.Map;
/**
* Class that maintains the complete set of servlet path matches.
*
*
* @author Stuart Douglas
*/
class ServletPathMatchesData {
private final Map exactPathMatches;
private final SubstringMap prefixMatches;
private final Map nameMatches;
ServletPathMatchesData(final Map exactPathMatches, final SubstringMap prefixMatches, final Map nameMatches) {
this.prefixMatches = prefixMatches;
this.nameMatches = nameMatches;
Map newExactPathMatches = new HashMap<>();
for (Map.Entry entry : exactPathMatches.entrySet()) {
newExactPathMatches.put(entry.getKey(), new ServletPathMatch(entry.getValue(), entry.getKey(), entry.getValue().isDefaultServletMapping()));
}
this.exactPathMatches = newExactPathMatches;
}
public ServletChain getServletHandlerByName(final String name) {
return nameMatches.get(name);
}
public ServletPathMatch getServletHandlerByExactPath(final String path) {
return exactPathMatches.get(path);
}
public ServletPathMatch getServletHandlerByPath(final String path) {
ServletPathMatch exact = exactPathMatches.get(path);
if (exact != null) {
return exact;
}
SubstringMap.SubstringMatch match = prefixMatches.get(path, path.length());
if (match != null) {
return handleMatch(path, match.getValue(), path.lastIndexOf('.'));
}
int extensionPos = -1;
for (int i = path.length() - 1; i >= 0; --i) {
final char c = path.charAt(i);
if (c == '/') {
match = prefixMatches.get(path, i);
if (match != null) {
return handleMatch(path, match.getValue(), extensionPos);
}
} else if (c == '.' && extensionPos == -1) {
extensionPos = i;
}
}
//this should never happen
//as the default servlet is aways registered under /*
throw UndertowMessages.MESSAGES.servletPathMatchFailed();
}
private ServletPathMatch handleMatch(final String path, final PathMatch match, final int extensionPos) {
if (match.extensionMatches.isEmpty()) {
return new ServletPathMatch(match.defaultHandler, path, match.requireWelcomeFileMatch);
}
if (extensionPos == -1) {
return new ServletPathMatch(match.defaultHandler, path, match.requireWelcomeFileMatch);
}
final String ext;
ext = path.substring(extensionPos + 1, path.length());
ServletChain handler = match.extensionMatches.get(ext);
if (handler != null) {
return new ServletPathMatch(handler, path, handler.getManagedServlet().getServletInfo().isRequireWelcomeFileMapping());
}
return new ServletPathMatch(match.defaultHandler, path, match.requireWelcomeFileMatch);
}
public static Builder builder() {
return new Builder();
}
public static final class Builder {
private final Map exactPathMatches = new HashMap<>();
private final SubstringMap prefixMatches = new SubstringMap();
private final Map nameMatches = new HashMap<>();
public void addExactMatch(final String exactMatch, final ServletChain match) {
exactPathMatches.put(exactMatch, match);
}
public void addPrefixMatch(final String prefix, final ServletChain match, final boolean requireWelcomeFileMatch) {
SubstringMap.SubstringMatch mt = prefixMatches.get(prefix);
PathMatch m;
if (mt == null) {
prefixMatches.put(prefix, m = new PathMatch(match));
} else {
m = mt.getValue();
}
m.defaultHandler = match;
m.requireWelcomeFileMatch = requireWelcomeFileMatch;
}
public void addExtensionMatch(final String prefix, final String extension, final ServletChain match) {
SubstringMap.SubstringMatch mt = prefixMatches.get(prefix);
PathMatch m;
if (mt == null) {
prefixMatches.put(prefix, m = new PathMatch(null));
} else {
m = mt.getValue();
}
m.extensionMatches.put(extension, match);
}
public void addNameMatch(final String name, final ServletChain match) {
nameMatches.put(name, match);
}
public ServletPathMatchesData build() {
return new ServletPathMatchesData(exactPathMatches, prefixMatches, nameMatches);
}
}
private static class PathMatch {
private final Map extensionMatches = new HashMap<>();
private volatile ServletChain defaultHandler;
private volatile boolean requireWelcomeFileMatch;
PathMatch(final ServletChain defaultHandler) {
this.defaultHandler = defaultHandler;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy