/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.eclipse.webdav.client;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Hashtable;
import org.eclipse.webdav.internal.kernel.utils.Assert;
/**
* A <code>URLTable</code> is a simple hashtable whose keys are
* <code>URL</code>s. A <code>URL<code> key with a trailing slash is
* considered by the table to be equal to the same <code>URL</code>
* without a trailing slash.
* <p>
* <b>Note:</b> This class/interface is part of an interim API that is still under
* development and expected to change significantly before reaching stability.
* It is being made available at this early stage to solicit feedback from pioneering
* adopters on the understanding that any code that uses this API will almost
* certainly be broken (repeatedly) as the API evolves.
* </p>
*/
public class URLTable {
private Hashtable table;
/**
* A <code>URLKey</code> is an equality wrapper class for
* <code>URL</code>s. The wrapper treats <code>URL</code>s with and
* without a trailing slash as equal. The <code>equals</code> method
* works with <code>URLKey</code>s, <code>URL</code>s, and
* <code>String</code>s.
* <p>
* <b>Note:</b> This class/interface is part of an interim API that is still under
* development and expected to change significantly before reaching stability.
* It is being made available at this early stage to solicit feedback from pioneering
* adopters on the understanding that any code that uses this API will almost
* certainly be broken (repeatedly) as the API evolves.
* </p>
*/
class URLKey {
URL url;
int hashCode = -1;
/**
* Creates a new <code>URLKey</code> from the given <code>URL</code>.
*
* @param url the <code>URL</code> to wrap
*/
public URLKey(URL url) {
this.url = url;
}
/**
* Returns <code>true</code> if this <code>URLKey</code> is equal to the
* given object. Returns <code>false</code> otherwise. The object may be
* a <code>URLKey<code>, <code>String</code>, or <code>URL</code>.
*
* @param obj the object to compare with this <code>URLKey</code>
* @return a boolean indicating whether or not this
* <code>URLKey</code> is equal to the given object
*/
public boolean equals(Object obj) {
if (obj == null)
return false;
if (this == obj)
return true;
if (obj instanceof URLKey)
return equals(((URLKey) obj).getURL());
if (obj instanceof String) {
try {
return equals(new URL((String) obj));
} catch (MalformedURLException e) {
return false;
}
}
if (!(obj instanceof URL))
return false;
if (url == (URL) obj)
return true;
URL url1 = URLTool.removeTrailingSlash(url);
URL url2 = URLTool.removeTrailingSlash((URL) obj);
return url1.equals(url2);
}
/**
* Returns the <code>URL</code> that this <code>URLKey</code> wraps.
*
* @return the <code>URL</code> that this <code>URLKey</code> wraps
*/
public URL getURL() {
return url;
}
/**
* Returns an integer suitable for indexing this <code>URLKey</code> in
* a hash table.
*
* @return an integer suitable for hash table indexing
*/
public int hashCode() {
if (hashCode == -1)
hashCode = URLTool.removeTrailingSlash(url).hashCode();
return hashCode;
}
/**
* Returns this <code>URLKey</code>s <code>URL</code> as a
* <code>String</code>.
*
* @return a string
*/
public String toString() {
return url.toString();
}
} // end-class URLKey
/**
* Construct an empty <code>URLTable</code>.
*/
public URLTable() {
table = new Hashtable();
}
/**
* Construct an empty <code>URLTable</code> with the given size.
*/
public URLTable(int size) {
table = new Hashtable(size);
}
/**
* Returns the value to which the given URL is mapped to in the table. If
* the given URL not mapped to any value, or is malformed, returns
* <code>null</code>.
*
* @param url a URL as a <code>String</code>
* @return the value to which the given URL is mapped to in the table,
* or <code>null</code>
* @throws MalformedURLException if the given URL is malformed
*/
public Object get(String url) throws MalformedURLException {
Assert.isNotNull(url);
return get(new URL(url));
}
/**
* Returns the value to which the given <code>URL</code> is mapped to in
* the table. If the given <code>URL</code> not mapped to any value,
* returns <code>null</code>.
*
* @param url a <code>URL</code>
* @return the value to which the given <code>URL</code> is mapped to
* in the table, or <code>null</code>
*/
public Object get(URL url) {
Assert.isNotNull(url);
return get(new URLKey(url));
}
/**
* Returns the value to which the specified URL is mapped to in the
* table. If the specified URL is not mapped to any value, returns
* <code>null</code>.
*
* @param url a <code>URLKey</code>
* @return the value to which the specified URL is mapped to in the
* table, or <code>null</code>
*/
private Object get(URLKey url) {
Assert.isNotNull(url);
return table.get(url);
}
/**
* Returns an <code>Enumeration</code> over the keys in this
* <code>URLTable</code>.
*
* @return an <code>Enumeration</code> over <code>URL</code>s
*/
public Enumeration keys() {
final Enumeration keys = table.keys();
Enumeration e = new Enumeration() {
public boolean hasMoreElements() {
return keys.hasMoreElements();
}
public Object nextElement() {
return ((URLKey) keys.nextElement()).getURL();
}
};
return e;
}
/**
* Maps the given URL to the given value in this table.
*
* @param url a URL as a <code>String</code>
* @param value an object
* @throws MalformedURLException if the given URL is malformed
*/
public void put(String url, Object value) throws MalformedURLException {
Assert.isNotNull(url);
Assert.isNotNull(value);
put(new URL(url), value);
}
/**
* Maps the given <code>URL</code> to the given value in this table.
*
* @param url a <code>URL</code>
* @param value an object
*/
public void put(URL url, Object value) {
Assert.isNotNull(url);
Assert.isNotNull(value);
put(new URLKey(url), value);
}
/**
* Maps the specified URL to the given value in this table.
*
* @param url a <code>URLKey</code>
* @param value an object
*/
private void put(URLKey url, Object value) {
Assert.isNotNull(url);
Assert.isNotNull(value);
// Remove the old entry so the url key is replaced
if (table.get(url) != null)
table.remove(url);
table.put(url, value);
}
public void remove(String url) throws MalformedURLException {
Assert.isNotNull(url);
remove(new URL(url));
}
public void remove(URL url) {
Assert.isNotNull(url);
remove(new URLKey(url));
}
private void remove(URLKey url) {
Assert.isNotNull(url);
table.remove(url);
}
}