package org.jboss.resteasy.core.registry; import org.jboss.resteasy.core.ResourceInvoker; import org.jboss.resteasy.core.ResourceMethodInvoker; import org.jboss.resteasy.spi.HttpRequest; import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedMap; import java.lang.reflect.Method; import java.util.List; import java.util.Map; /** * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @version $Revision: 1 $ */ public class RootNode { protected SegmentNode root = new SegmentNode(""); protected int size = 0; protected MultivaluedMap<String, MethodExpression> bounded = new MultivaluedHashMap<String, MethodExpression>(); public int getSize() { return size; } public MultivaluedMap<String, ResourceInvoker> getBounded() { MultivaluedHashMap<String, ResourceInvoker> rtn = new MultivaluedHashMap<String, ResourceInvoker>(); for (Map.Entry<String, List<MethodExpression>> entry : bounded.entrySet()) { for (MethodExpression exp : entry.getValue()) { rtn.add(entry.getKey(), exp.getInvoker()); } } return rtn; } public ResourceInvoker match(HttpRequest request, int start) { return root.match(request, start); } public void removeBinding(String path, Method method) { List<MethodExpression> expressions = bounded.get(path); if (expressions == null) return; for (MethodExpression expression : expressions) { ResourceInvoker invoker = expression.getInvoker(); if (invoker.getMethod().equals(method)) { expression.parent.targets.remove(expression); expressions.remove(expression); if (expressions.size() == 0) bounded.remove(path); size--; if (invoker instanceof ResourceMethodInvoker) { ((ResourceMethodInvoker)invoker).cleanup(); } return; } } } public void addInvoker(String path, ResourceInvoker invoker) { MethodExpression expression = addExpression(path, invoker); size++; bounded.add(path, expression); } protected MethodExpression addExpression(String path, ResourceInvoker invoker) { if (path.startsWith("/")) path = path.substring(1); if (path.endsWith("/")) path = path.substring(0, path.length() - 1); if ("".equals(path)) { if (invoker instanceof ResourceMethodInvoker) { MethodExpression expression = new MethodExpression(root, "", invoker); root.addExpression(expression); return expression; } else { MethodExpression expression = new MethodExpression(root, "", invoker, "(.*)"); root.addExpression(expression); return expression; } } String expression = null; MethodExpression exp; //Matcher param = PathHelper.URI_PARAM_PATTERN.matcher(path); int expidx = path.indexOf('{'); if (expidx > -1) { int i =expidx; while (i - 1 > -1) { if (path.charAt(i - 1) == '/') { break; } i--; } String staticPath = null; if (i > 0) staticPath = path.substring(0, i - 1); SegmentNode node = root; if (staticPath != null) { String[] split = staticPath.split("/"); for (String segment : split) { SegmentNode tmp = node.children.get(segment); if (tmp == null) { tmp = new SegmentNode(segment); node.children.put(segment, tmp); } node = tmp; } } if (invoker instanceof ResourceMethodInvoker) { exp = new MethodExpression(node, path, invoker); } else { exp = new MethodExpression(node, path, invoker, "(/.+)?"); } node.addExpression(exp); } else { String[] split = path.split("/"); SegmentNode node = root; for (String segment : split) { SegmentNode tmp = node.children.get(segment); if (tmp == null) { tmp = new SegmentNode(segment); node.children.put(segment, tmp); } node = tmp; } if (invoker instanceof ResourceMethodInvoker) { exp = new MethodExpression(node, path, invoker); node.addExpression(exp); } else { exp = new MethodExpression(node, path, invoker, "(.*)"); node.addExpression(exp); } } return exp; } }