/* *************************************************************************************** * Copyright (C) 2006 EsperTech, Inc. All rights reserved. * * http://www.espertech.com/esper * * http://www.espertech.com * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the GPL license * * a copy of which has been included with this distribution in the license.txt file. * *************************************************************************************** */ package com.espertech.esper.util; import java.net.URI; import java.util.Collection; import java.util.Map; import java.util.TreeMap; /** * Utility for inspecting and comparing URI. */ public class URIUtil { /** * Given a child URI and a map of factory URIs, inspect the child URI against the factory URIs * and return a collection of entries for which the child URI falls within or is equals to the factory URI. * * @param child is the child URI to match against factory URIs * @param uris is a map of factory URI and an object * @return matching factory URIs, if any */ public static Collection<Map.Entry<URI, Object>> filterSort(URI child, Map<URI, Object> uris) { boolean childPathIsOpaque = child.isOpaque(); boolean childPathIsRelative = !child.isAbsolute(); String[] childPathElements = parsePathElements(child); TreeMap<Integer, Map.Entry<URI, Object>> result = new TreeMap<Integer, Map.Entry<URI, Object>>(); for (Map.Entry<URI, Object> entry : uris.entrySet()) { URI facoryUri = entry.getKey(); // handle opaque (mailto:) and relative (a/b) using equals if (childPathIsOpaque || childPathIsRelative || !facoryUri.isAbsolute() || facoryUri.isOpaque()) { if (facoryUri.equals(child)) { result.put(Integer.MIN_VALUE, entry); // Equals is a perfect match } continue; } // handle absolute URIs, compare scheme and authority if present if (((child.getScheme() != null) && (facoryUri.getScheme() == null)) || ((child.getScheme() == null) && (facoryUri.getScheme() != null))) { continue; } if ((child.getScheme() != null) && (!child.getScheme().equals(facoryUri.getScheme()))) { continue; } if (((child.getAuthority() != null) && (facoryUri.getAuthority() == null)) || ((child.getAuthority() == null) && (facoryUri.getAuthority() != null))) { continue; } if ((child.getAuthority() != null) && (!child.getAuthority().equals(facoryUri.getAuthority()))) { continue; } // Match the child String[] factoryPathElements = parsePathElements(facoryUri); int score = computeScore(childPathElements, factoryPathElements); if (score > 0) { result.put(score, entry); // Partial match if score is positive } } return result.values(); } public static String[] parsePathElements(URI uri) { String path = uri.getPath(); if (path == null) { return new String[0]; } while (path.startsWith("/")) { path = path.substring(1); } String[] split = path.split("/"); if ((split.length > 0) && (split[0].length() == 0)) { return new String[0]; } return split; } private static int computeScore(String[] childPathElements, String[] factoryPathElements) { int index = 0; if (factoryPathElements.length == 0) { return Integer.MAX_VALUE; // the most general factory scores the lowest } while (true) { if ((childPathElements.length > index) && (factoryPathElements.length > index)) { if (!(childPathElements[index].equals(factoryPathElements[index]))) { return 0; } } else { if (childPathElements.length <= index) { if (factoryPathElements.length > index) { return 0; } return Integer.MAX_VALUE - index - 1; } } if (factoryPathElements.length <= index) { break; } index++; } return Integer.MAX_VALUE - index - 1; } }