Java tutorial
/* * Weblounge: Web Content Management System * Copyright (c) 2003 - 2011 The Weblounge Team * http://entwinemedia.com/weblounge * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package ch.entwine.weblounge.common.url; import ch.entwine.weblounge.common.site.Site; import org.apache.commons.lang.StringUtils; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.Iterator; import java.util.TreeSet; import javax.servlet.http.HttpServletRequest; /** * <code>UrlUtils</code> is a helper class to deal with urls. */ public final class UrlUtils { /** * This class should not be instantiated, since it provides static utility * methods only. */ private UrlUtils() { // Nothing to be done here } /** * Sorts the given urls by path. * * @param urls * the urls to sort * @return the sorted urls */ public static String[] sort(String[] urls) { TreeSet<String> set = new TreeSet<String>(); for (int i = 0; i < urls.length; i++) set.add(urls[i]); String[] result = new String[urls.length]; Iterator<String> i = set.iterator(); int index = 0; while (i.hasNext()) { result[index++] = i.toString(); } return result; } /** * Concatenates the url elements with respect to leading and trailing slashes. * The path will always end with a trailing slash. * * @param urlElements * the path elements * @return the concatenated url of the two arguments * @throws IllegalArgumentException * if less than two path elements are provided */ public static String concat(String... urlElements) throws IllegalArgumentException { if (urlElements == null || urlElements.length < 1) throw new IllegalArgumentException("Prefix cannot be null or empty"); if (urlElements.length < 2) throw new IllegalArgumentException("Suffix cannot be null or empty"); StringBuffer b = new StringBuffer(); for (String s : urlElements) { if (StringUtils.isBlank(s)) throw new IllegalArgumentException("Path element cannot be null"); String element = checkSeparator(s); element = removeDoubleSeparator(element); if (b.length() == 0) { b.append(element); } else if (b.lastIndexOf("/") < b.length() - 1 && !element.startsWith("/")) { b.append("/").append(element); } else if (b.lastIndexOf("/") == b.length() - 1 && element.startsWith("/")) { b.append(element.substring(1)); } else { b.append(element); } } return b.toString(); } /** * Returns the trimmed url. Trimmed means that the url is free from leading or * trailing whitespace characters, and that a directory url like * <code>/news/</code> is closed by a slash (<code>/</code>). * * @param url * the url to trim * @return the trimmed url */ public static String trim(String url) { if (url == null) throw new IllegalArgumentException("Url cannot be null"); url = checkSeparator(url); url = removeDoubleSeparator(url); url = url.trim(); if (url.endsWith("/") || (url.length() == 1)) return url; int index = url.lastIndexOf("/"); int dotIndex = url.indexOf(".", index); int anchorIndex = url.indexOf("#", index); if (dotIndex == -1 && anchorIndex == -1) url += "/"; return url; } /** * Returns the link created from the given partition and path. This link will * include the weblounge mountpoint. * * @param site * the associated site * @param path * the database path * @return the link */ public static String getLink(Site site, String path) { return path; } /** * Checks that the path only contains the web path separator "/". If not, * wrong ones are replaced. */ private static String checkSeparator(String path) { String sp = File.separator; if ("\\".equals(sp)) sp = "\\\\"; return path.replaceAll(sp, "/"); } /** * Removes any occurrence of double separators ("//") and replaces it with * "/". * * @param path * the path to check * @return the corrected path */ private static String removeDoubleSeparator(String path) { int protocolIndex = path.indexOf("://"); protocolIndex += protocolIndex == -1 ? 0 : 3; int index = Math.max(0, protocolIndex); while ((index = path.indexOf("//", index)) != -1) { path = path.substring(0, index) + path.substring(index + 1); } return path; } /** * Returns <code>true</code> if url <code>a</code> is a direct prefix of url * <code>b</code>. For example, <code>/news</code> is the parent of * <code>/news/today</code>. * <p> * Note that <code>a</code> is also an extended prefix of <code>b</code> if * <code>a</code> and <code>b</code> are equal. * * @param a * the first url * @param b * the second url * @return <code>true</code> if <code>a</code> is the direct prefix of * <code>b</code> */ public static boolean isPrefix(String a, String b) { if (isExtendedPrefix(a, b)) { if (a.length() < b.length()) { String bRest = b.substring(a.length() + 1); if (bRest.endsWith("/")) bRest = bRest.substring(0, bRest.length() - 2); return bRest.indexOf("/", 1) < 0; } else { return true; } } return false; } /** * Returns <code>true</code> if url <code>a</code> is a prefix of url * <code>b</code>. For example, <code>/news</code> is an ancestor of * <code>/news/today/morning</code>. * <p> * Note that <code>a</code> is also an extended prefix of <code>b</code> if * <code>a</code> and <code>b</code> are equal. * * @param a * the first url * @param b * the second url * @return <code>true</code> if <code>a</code> is a prefix of <code>b</code> */ public static boolean isExtendedPrefix(String a, String b) { if (b.startsWith(a)) { if (b.length() > a.length()) return a.endsWith("/") || b.substring(a.length()).startsWith("/"); else return true; } return false; } /** * Returns the url extension that <code>url</code> defines over * <code>prefix</code>. For example, the extension of url * <code>/news/today</code> and prefix <code>/news</code> is * <code>today</code>. * <p> * If <code>prefix</code> is not a prefix of <code>url</code>, this method * returns <code>null</code>, if <code>url</code> and <code>prefix</code> * match, the empty string is returned. * * @param prefix * the url prefix * @param url * the url * @return the url extension over the prefix */ public static String getExtension(String prefix, String url) { prefix = prefix.trim(); if (isExtendedPrefix(prefix, url)) { if (url.length() > prefix.length()) { String extension = url.substring(prefix.length() + 1); if (extension.endsWith("/")) { extension = extension.substring(0, extension.length() - 1); } return extension; } else return ""; } return null; } /** * Returns the extension that is encoded into the url. Possible extensions * are: * <ul> * <li>/*</li> * <li>/**</li> * <li><code>null</code></li> * </ul> * * @param url * the url with extension * @return the url extension or <code>null</code> if no extension can be found */ public static String getExtension(String url) { if (url.endsWith("/**")) return "/**"; else if (url.endsWith("/*")) return "/*"; else return null; } /** * Strips off the extension and returns the pure url. * * @param url * the url with extension * @return the url */ public static String stripExtension(String url) { String extension = getExtension(url); if (extension == null) return url; else return url.substring(0, url.length() - extension.length()); } /** * Returns <code>true</code> if the url is valid, that is, if it contains only * allowed characters. * * @return <code>true</code> or the invalid character */ public static boolean isValid(String url) { return (checkUrl(url) == null); } /** * Returns <code>null</code> if the url is valid, that is, if it contains only * allowed characters. otherwise, the invalid character is returned. * * @return <code>null</code> or the invalid character */ public static Character getInvalidCharacter(String url) { Character c = checkUrl(url); return c; } /** * Returns <code>null</code> if the url is valid, that is, if it contains only * allowed characters. otherwise, the invalid character is returned. * * @return <code>null</code> or the invalid character */ private static Character checkUrl(String url) { StringBuffer original = new StringBuffer(url); for (int i = 0; i < original.length(); i++) { int value = original.charAt(i); // a-z if (value >= 'a' && value <= 'z') { continue; } // A-Z if (value >= 'A' && value <= 'Z') { continue; } // 0-9 if (value >= '0' && value <= '9') { continue; } // Special characters if (value == '-' || value == '_' || value == '.' || value == ',' || value == ';') { continue; } return original.charAt(i); } return null; } /** * Returns the request url as a string. * * @param request * the request * @param includePath * <code>true</code> to also include the request uri * @param includeQuery * <code>true</code> to include the query string * @return the url as a string */ public static URL toURL(HttpServletRequest request, boolean includePath, boolean includeQuery) { try { StringBuffer buf = new StringBuffer(request.getScheme()); buf.append("://"); buf.append(request.getServerName()); if (request.getServerPort() != 80) buf.append(":").append(request.getServerPort()); if (includePath && request.getRequestURI() != null) buf.append(request.getRequestURI()); if (includeQuery && StringUtils.isNotBlank(request.getQueryString())) buf.append(request.getQueryString()); return new URL(buf.toString()); } catch (MalformedURLException e) { throw new IllegalStateException(e); } } }