use of org.eclipse.jetty.util.ArrayTernaryTrie in project jetty.project by eclipse.
the class ContextHandlerCollection method mapContexts.
/* ------------------------------------------------------------ */
/**
* Remap the context paths.
*/
@ManagedOperation("update the mapping of context path to context")
public void mapContexts() {
_contextBranches.clear();
if (getHandlers() == null) {
_pathBranches = new ArrayTernaryTrie<>(false, 16);
return;
}
// Create map of contextPath to handler Branch
Map<String, Branch[]> map = new HashMap<>();
for (Handler handler : getHandlers()) {
Branch branch = new Branch(handler);
for (String contextPath : branch.getContextPaths()) {
Branch[] branches = map.get(contextPath);
map.put(contextPath, ArrayUtil.addToArray(branches, branch, Branch.class));
}
for (ContextHandler context : branch.getContextHandlers()) _contextBranches.putIfAbsent(context, branch.getHandler());
}
// Sort the branches so those with virtual hosts are considered before those without
for (Map.Entry<String, Branch[]> entry : map.entrySet()) {
Branch[] branches = entry.getValue();
Branch[] sorted = new Branch[branches.length];
int i = 0;
for (Branch branch : branches) if (branch.hasVirtualHost())
sorted[i++] = branch;
for (Branch branch : branches) if (!branch.hasVirtualHost())
sorted[i++] = branch;
entry.setValue(sorted);
}
// Loop until we have a big enough trie to hold all the context paths
int capacity = 512;
Trie<Map.Entry<String, Branch[]>> trie;
loop: while (true) {
trie = new ArrayTernaryTrie<>(false, capacity);
for (Map.Entry<String, Branch[]> entry : map.entrySet()) {
if (!trie.put(entry.getKey().substring(1), entry)) {
capacity += 512;
continue loop;
}
}
break loop;
}
if (LOG.isDebugEnabled()) {
for (String ctx : trie.keySet()) LOG.debug("{}->{}", ctx, Arrays.asList(trie.get(ctx).getValue()));
}
_pathBranches = trie;
}
use of org.eclipse.jetty.util.ArrayTernaryTrie in project jetty.project by eclipse.
the class PathMap method put.
/* --------------------------------------------------------------- */
/** Add a single path match to the PathMap.
* @param pathSpec The path specification, or comma separated list of
* path specifications.
* @param object The object the path maps to
*/
@Override
public O put(String pathSpec, O object) {
if ("".equals(pathSpec.trim())) {
MappedEntry<O> entry = new MappedEntry<>("", object);
entry.setMapped("");
_exactMap.put("", entry);
return super.put("", object);
}
StringTokenizer tok = new StringTokenizer(pathSpec, __pathSpecSeparators);
O old = null;
while (tok.hasMoreTokens()) {
String spec = tok.nextToken();
if (!spec.startsWith("/") && !spec.startsWith("*."))
throw new IllegalArgumentException("PathSpec " + spec + ". must start with '/' or '*.'");
old = super.put(spec, object);
// Make entry that was just created.
MappedEntry<O> entry = new MappedEntry<>(spec, object);
if (entry.getKey().equals(spec)) {
if (spec.equals("/*"))
_prefixDefault = entry;
else if (spec.endsWith("/*")) {
String mapped = spec.substring(0, spec.length() - 2);
entry.setMapped(mapped);
while (!_prefixMap.put(mapped, entry)) _prefixMap = new ArrayTernaryTrie<>((ArrayTernaryTrie<MappedEntry<O>>) _prefixMap, 1.5);
} else if (spec.startsWith("*.")) {
String suffix = spec.substring(2);
while (!_suffixMap.put(suffix, entry)) _suffixMap = new ArrayTernaryTrie<>((ArrayTernaryTrie<MappedEntry<O>>) _suffixMap, 1.5);
} else if (spec.equals(URIUtil.SLASH)) {
if (_nodefault)
_exactMap.put(spec, entry);
else {
_default = entry;
_defaultSingletonList = Collections.singletonList(_default);
}
} else {
entry.setMapped(spec);
_exactMap.put(spec, entry);
}
}
}
return old;
}
Aggregations