/* * 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.impl.url; import ch.entwine.weblounge.common.url.Path; /** * This class implements common url and path behavior. */ public class UrlImpl implements Path { /** Serial version uid */ private static final long serialVersionUID = 3314907623908539157L; /** Default path separator */ private static final char URL_PATH_SEPARATOR = '/'; /** The url that is represented */ protected String path = null; /** The path separator */ protected String pathElementSeparator = null; /** The path separator character */ protected char pathElementSeparatorChar = 0; /** Static constant used to filter out double path separators */ protected String doublePathElementSeparator = null; /** * Creates a new url from a given path using the default path separator * <code>"/"</code>. * * @param path * the url path */ public UrlImpl(String path) { this(path, URL_PATH_SEPARATOR); } /** * Creates a new url from a given path using the default path separator * <code>"/"</code>. * * @param url * the parent url * @param path * the url path */ public UrlImpl(Path url, String path) { this(concat(url.getPath(), path, url.getPathSeparator()), url.getPathSeparator()); } /** * Creates a new url from a given path and separator. * * @param path * the url path * @param separator * the path separator */ public UrlImpl(String path, char separator) { this.pathElementSeparatorChar = separator; this.pathElementSeparator = Character.toString(separator); // Build the double path separator StringBuffer buf = new StringBuffer(); buf.append(separator).append(separator); if ('\\' == separator) buf.append(separator).append(separator); this.doublePathElementSeparator = buf.toString(); if (path != null) setPath(path); } /** * Creates a url pointing to root with the given separator. * * @param separator * the path separator character */ protected UrlImpl(char separator) { this(null, separator); this.path = "/"; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.url.Path#getPathSeparator() */ public char getPathSeparator() { return pathElementSeparatorChar; } /** * Sets the path. * * @param path the path */ public void setPath(String path) { this.path = trim(path); if (this.path != null && !this.path.startsWith(Character.toString(pathElementSeparatorChar))) this.path = pathElementSeparatorChar + this.path; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.url.Path#getPath() */ public String getPath() { return path; } /** * Returns the parent path or <code>null</code> if the current path has now * parent, i. e. the current path represents the root. * * @return the parent path */ protected String getParentPath() { String separator = Character.toString(pathElementSeparatorChar); if (path.equals(separator)) return null; String p = path; if (p.endsWith(separator)) p = path.substring(0, path.length() - 1); int lastSeparator = p.lastIndexOf(pathElementSeparatorChar); return (lastSeparator > 0) ? path.substring(0, lastSeparator) : separator; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.url.Path#startsWith(java.lang.String) */ public boolean startsWith(String path) { if (path == null) throw new IllegalArgumentException("Cannot contain null string!"); String trimmedPathelement = trim(path); return this.path.startsWith(trimmedPathelement); } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.url.Path#endsWith(java.lang.String) */ public boolean endsWith(String path) { if (path == null) throw new IllegalArgumentException("Cannot contain null string!"); String trimmedPathelement = trim(path); return this.path.endsWith(trimmedPathelement); } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.url.Path#isPrefixOf(ch.entwine.weblounge.common.url.Path) */ public boolean isPrefixOf(Path url) { if (url == null) throw new IllegalArgumentException("Cannot be prepended by null!"); return url.getPath().indexOf(path) == 0; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.url.Path#isExtensionOf(ch.entwine.weblounge.common.url.Path) */ public boolean isExtensionOf(Path url) { return path.indexOf(url.getPath()) == 0; } /** * Concatenates the two urls with respect to leading and trailing slashes. * * @return the concatenated url of the two arguments */ protected static String concat(String prefix, String suffix, char separatorChar) { if (prefix == null) throw new IllegalArgumentException("Prefix cannot be null"); if (suffix == null) throw new IllegalArgumentException("Suffix cannot be null"); String separator = Character.toString(separatorChar); if (!prefix.endsWith(separator) && !suffix.startsWith(separator)) prefix += separator; if (prefix.endsWith(separator) && suffix.startsWith(separator)) suffix = suffix.substring(1); prefix += suffix; return prefix; } /** * 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 */ protected String trim(String url) { if (url == null) return null; url = url.trim().toLowerCase(); url = url.replace(doublePathElementSeparator, pathElementSeparator); if (url.endsWith(pathElementSeparator) || url.equals(pathElementSeparator)) return url; int index = url.lastIndexOf(pathElementSeparator); int dotIndex = url.indexOf(".", index); int anchorIndex = url.indexOf("#", index); if (dotIndex == -1 && anchorIndex == -1) url += pathElementSeparator; return url; } /** * {@inheritDoc} * * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return path.hashCode(); } /** * {@inheritDoc} * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (obj != null && obj instanceof Path) { Path url = (Path) obj; return path.equals(url.getPath()); } return super.equals(obj); } /** * Returns the <code>String</code> representation of this object, which is * equal to the url's path as returned by {@link #getPath()}. * * @return the path * @see java.lang.Object#toString() */ @Override public String toString() { return path; } }