/* * Copyright 2012 Jason Miller * * 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 jj.http.server.uri; import io.netty.handler.codec.http.HttpMethod; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; /** * @author jason * */ abstract class TrieNode { static final char PATH_SEPARATOR_CHAR = '/'; static final char EXTENSION_SEPARATOR_CHAR = '.'; static final String PATH_SEPARATOR_STRING = String.valueOf(PATH_SEPARATOR_CHAR); static final String EXTENSION_SEPARATOR_STRING = String.valueOf(EXTENSION_SEPARATOR_CHAR); static final String PARAM_CHARS = ":*"; // this is set to true on a SeparatorNode if an exntension is found at the end of // a route. it indicates that after the separator, no node type switches are allowed boolean terminal; Map<HttpMethod, Route> goal; void addRoute(Route route) { if (route.uri().length() == route.index()) { goal = goal == null ? new LinkedHashMap<>(3) : goal; if (goal.containsKey(route.method())) { throw new IllegalArgumentException( "duplicate " + route + ", current config = " + goal ); } goal.put(route.method(), route); route.added(); } else { doAddChild(route); } } abstract void doAddChild(Route route); abstract boolean findGoal(RouteFinderContext context, String uri, int index); private void compressGoal() { if (goal != null) { if (goal.size() == 1) { HttpMethod key = goal.keySet().iterator().next(); goal = Collections.singletonMap(key, goal.get(key)); } else { goal = Collections.unmodifiableMap(goal); } } } void compress() { doCompress(); compressGoal(); } abstract void doCompress(); abstract StringBuilder describe(int indent, StringBuilder sb); StringBuilder addIndentation(int indent, StringBuilder sb) { for (; indent > 0; --indent) { sb.append(' '); } return sb; } abstract void describeChildren(int indent, StringBuilder sb); @Override public String toString() { StringBuilder sb = new StringBuilder(); describe(0, sb); return sb.toString(); } }