private Match createMatch( MatchSegment bestMatchSegment, PathNode bestPath, QueryNode bestQuery, Template input) { Match match = null; if (bestPath != null) { // && ( bestQuery != null || !bestPath.hasQueries() ) ) { if (bestQuery != null) { match = new Match(bestQuery.template, bestQuery.value); } else { match = new Match(bestPath.template, bestPath.value); } MatchParams matchParams = new MatchParams(); // Add the matching query segments to the end of the list. if (bestQuery != null) { Map<String, Query> inputQuery = input.getQuery(); for (Query templateSegment : bestQuery.template.getQuery().values()) { Query inputSegment = inputQuery.get(templateSegment.getQueryName()); if (inputSegment != null && templateSegment.matches(inputSegment)) { extractSegmentParams(templateSegment, inputSegment, matchParams); } } } // If the template has the "extra" query queryParam then collect query params that were // not already matched. if (bestQuery != null) { Query extra = bestQuery.template.getExtra(); if (extra != null) { String paramName = extra.getParamName(); if (paramName != null && paramName.length() > 0) { for (Query query : input.getQuery().values()) { String queryName = query.getQueryName(); if (matchParams.resolve(queryName) == null) { for (Segment.Value value : query.getValues()) { matchParams.addValue(queryName, value.getEffectivePattern()); } } } } } } // Walk back up the matching segment tree. MatchSegment matchSegment = bestMatchSegment; while (matchSegment != null && matchSegment.pathNode.depth > 0) { extractSegmentParams(matchSegment.templateSegment, matchSegment.inputSegment, matchParams); matchSegment = matchSegment.parentMatch; } match.params = matchParams; } return match; }
private int calcQueryMatchCount(QueryNode node, Template input) { int matchCount = 0; Map<String, Query> inputQuery = input.getQuery(); Map<String, Query> templateQuery = node.template.getQuery(); for (Query templateSegment : templateQuery.values()) { Query inputSegment = inputQuery.get(templateSegment.getQueryName()); if (inputSegment != null && templateSegment.matches(inputSegment)) { matchCount++; } else { matchCount = 0; break; } } return matchCount; }
private QueryNode pickBestQueryMatch(Template input, PathNode pathNode) { QueryNode bestNode = null; int bestMatchCount = 0; for (QueryNode node : pathNode.queries) { Query extra = node.template.getExtra(); int nodeQuerySize = node.template.getQuery().size(); int queryMatchCount = calcQueryMatchCount(node, input); boolean matchesNamedQueries = queryMatchCount >= nodeQuerySize; boolean matchesExtraQuery = ((extra == null) || (Segment.GLOB_PATTERN.equals(extra.getQueryName())) || (input.getQuery().size() > nodeQuerySize)); if ((bestNode == null || queryMatchCount > bestMatchCount) && (matchesNamedQueries && matchesExtraQuery)) { bestMatchCount = queryMatchCount; bestNode = node; } } return bestNode; }
public void add(Template template, V value) { map.put(template, value); PathNode node = root; // Add the scheme segment to the tree (if any) while descending. node = add(node, template.getScheme()); // Add the authority segments (if any) while descending. node = add(node, template.getUsername()); node = add(node, template.getPassword()); node = add(node, template.getHost()); node = add(node, template.getPort()); // Add the path segments while descending. for (Path segment : template.getPath()) { // If the root already contains a matching segment then descend to that pathNode. // Otherwise create a child pathNode, addValue it to the root and descend to it. // If this new pathNode is a leaf pathNode then set the value. node = add(node, segment); } // Add the fragment (if any) segments while descending. // Note: Doing it this way puts the fragment above the query parameters in the match order. node = add(node, template.getFragment()); if (template.getQuery().isEmpty() && template.getExtra() == null) { // The first template with a value at this node wins. if (node.value == null) { node.template = template; node.value = value; } } else { // Insert a query pathNode into the tree. node.addQuery(template, value); } }