
it.could.util.location.Parameters Maven / Gradle / Ivy
Show all versions of webdav Show documentation
/* ========================================================================== *
* Copyright (C) 2004-2006, Pier Fumagalli *
* All rights reserved. *
* ========================================================================== *
* *
* Licensed under the Apache License, Version 2.0 (the "License"). You may *
* not use this file except in compliance with the License. You may obtain a *
* copy of the License at . *
* *
* 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 it.could.util.location;
import it.could.util.StringTools;
import it.could.util.encoding.Encodable;
import it.could.util.encoding.EncodingTools;
import java.io.UnsupportedEncodingException;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* The {@link Parameters Parameters} class represents a never empty and
* immutable {@link List} of {@link Parameters.Parameter Parameter} instances,
* normally created parsing a query string.
*
* @author Pier Fumagalli
*/
public class Parameters extends AbstractList implements Encodable {
/** The default delimiter for a {@link Parameters} instance.
*/
public static final char DEFAULT_DELIMITER = '&';
/** All the {@link Parameter}s in order.
*/
private final Parameter parameters[];
/** The {@link Map} view over all parameters (names are keys).
*/
private final Map map;
/** The {@link Set} of all parameter names.
*/
final Set names;
/** The character delimiting different parameters.
*/
private final char delimiter;
/** The encoded {@link String} representation of this.
*/
private final String string;
/**
* Create a new {@link Parameters Parameters} instance from
* a {@link List} of {@link Parameters.Parameter Parameter} instances
* using the {@link #DEFAULT_DELIMITER default parameter delimiter}.
*
* @throws NullPointerExceptoin if the {@link List} was null.
* @throws IllegalArgumentException if the {@link List} was empty.
* @throws ClassCastException if any of the elements in the {@link List} was
* not a {@link Parameters.Parameter Parameter}.
*/
public Parameters(List parameters) {
this(parameters, DEFAULT_DELIMITER);
}
/**
* Create a new {@link Parameters Parameters} instance from
* a {@link List} of {@link Parameters.Parameter Parameter} instances
* using the specified character as the parameters delimiter.
*
* @throws NullPointerExceptoin if the {@link List} was null.
* @throws IllegalArgumentException if the {@link List} was empty.
* @throws ClassCastException if any of the elements in the {@link List} was
* not a {@link Parameters.Parameter Parameter}.
*/
public Parameters(List parameters, char delimiter) {
if (parameters.size() == 0) throw new IllegalArgumentException();
final Parameter array[] = new Parameter[parameters.size()];
final Map map = new HashMap();
for (int x = 0; x < array.length; x ++) {
final Parameter parameter = (Parameter) parameters.get(x);
final String key = parameter.getName();
List values = (List) map.get(key);
if (values == null) {
values = new ArrayList();
map.put(key, values);
}
values.add(parameter.getValue());
array[x] = parameter;
}
/* Make all parameter value lists unmodifiable */
for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) {
final Map.Entry entry = (Map.Entry) iter.next();
final List list = (List) entry.getValue();
entry.setValue(Collections.unmodifiableList(list));
}
/* Store the current values */
this.delimiter = delimiter;
this.map = Collections.unmodifiableMap(map);
this.names = Collections.unmodifiableSet(map.keySet());
this.parameters = array;
this.string = EncodingTools.toString(this);
}
/* ====================================================================== */
/* STATIC CONSTRUCTION METHODS */
/* ====================================================================== */
/**
* Utility method to create a new {@link Parameters} instance from a
* {@link List} of {@link Parameters.Parameter Parameter} instances.
*
* @return a non-null and not empty {@link Parameters} instance or
* null if the specified {@link List} was null, empty
* or did not contain any {@link Parameters.Parameter Parameter}.
* @throws ClassCastException if any of the elements in the {@link List} was
* not a {@link Parameters.Parameter Parameter}.
*/
public static Parameters create(List parameters) {
return create(parameters, DEFAULT_DELIMITER);
}
/**
* Utility method to create a new {@link Parameters} instance from a
* {@link List} of {@link Parameters.Parameter Parameter} instances.
*
* @return a non-null and not empty {@link Parameters} instance or
* null if the specified {@link List} was null, empty
* or did not contain any {@link Parameters.Parameter Parameter}.
* @throws ClassCastException if any of the elements in the {@link List} was
* not a {@link Parameters.Parameter Parameter}.
*/
public static Parameters create(List parameters, char delimiter) {
if (parameters == null) return null;
final List dedupes = new ArrayList();
for (Iterator iter = parameters.iterator(); iter.hasNext(); ) {
Object next = iter.next();
if (dedupes.contains(next)) continue;
dedupes.add(next);
}
if (dedupes.size() == 0) return null;
return new Parameters(dedupes, delimiter);
}
/**
* Parse the specified parameters {@link String} into a
* {@link Parameters} instance using the {@link #DEFAULT_DELIMITER default
* parameter delimiter}.
*
* @return a non-null and not empty {@link Parameters} instance or
* null if the specified string was null, empty or
* did not contain any {@link Parameters.Parameter Parameter}.
*/
public static Parameters parse(String parameters) {
try {
return parse(parameters, DEFAULT_DELIMITER, DEFAULT_ENCODING);
} catch (UnsupportedEncodingException exception) {
final String message = "Unsupported encoding " + DEFAULT_ENCODING;
final InternalError error = new InternalError(message);
throw (InternalError) error.initCause(exception);
}
}
/**
* Parse the specified parameters {@link String} into a
* {@link Parameters} instance using the specified character as the
* parameters delimiter.
*
* @return a non-null and not empty {@link Parameters} instance or
* null if the specified string was null, empty or
* did not contain any {@link Parameters.Parameter Parameter}.
*/
public static Parameters parse(String parameters, char delimiter) {
try {
return parse(parameters, delimiter, DEFAULT_ENCODING);
} catch (UnsupportedEncodingException exception) {
final String message = "Unsupported encoding " + DEFAULT_ENCODING;
final InternalError error = new InternalError(message);
throw (InternalError) error.initCause(exception);
}
}
/**
* Parse the specified parameters {@link String} into a
* {@link Parameters} instance using the {@link #DEFAULT_DELIMITER default
* parameter delimiter}.
*
* @return a non-null and not empty {@link Parameters} instance or
* null if the specified string was null, empty or
* did not contain any {@link Parameters.Parameter Parameter}.
*/
public static Parameters parse(String parameters, String encoding)
throws UnsupportedEncodingException {
return parse(parameters, DEFAULT_DELIMITER, encoding);
}
/**
* Parse the specified parameters {@link String} into a
* {@link Parameters} instance using the specified character as the
* parameters delimiter.
*
* @return a non-null and not empty {@link Parameters} instance or
* null if the specified string was null, empty or
* did not contain any {@link Parameters.Parameter Parameter}.
*/
public static Parameters parse(String parameters, char delimiter,
String encoding)
throws UnsupportedEncodingException {
if (parameters == null) return null;
if (parameters.length() == 0) return null;
if (encoding == null) encoding = DEFAULT_ENCODING;
final String split[] = StringTools.splitAll(parameters, delimiter);
final List list = new ArrayList();
for (int x = 0; x < split.length; x ++) {
if (split[x] == null) continue;
if (split[x].length() == 0) continue;
Parameter parameter = Parameter.parse(split[x], encoding);
if (parameter != null) list.add(parameter);
}
if (list.size() == 0) return null;
return new Parameters(list, delimiter);
}
/* ====================================================================== */
/* PUBLIC EXPOSED METHODS */
/* ====================================================================== */
/**
* Return the number of {@link Parameters.Parameter Parameter}s
* contained by this instance.
*/
public int size() {
return this.parameters.length;
}
/**
* Return the {@link Parameters.Parameter Parameter} stored by this\
* instance at the specified index.
*/
public Object get(int index) {
return this.parameters[index];
}
/**
* Return an immutable {@link Set} of {@link String}s containing all
* known {@link Parameters.Parameter Parameter}
* {@link Parameters.Parameter#getName() names}.
*/
public Set getNames() {
return this.names;
}
/**
* Return the first {@link String} value associated with the
* specified parameter name, or null.
*/
public String getValue(String name) {
final List values = (List) this.map.get(name);
return values == null ? null : (String) values.get(0);
}
/**
* Return an immutable {@link List} of all {@link String} values
* associated with the specified parameter name, or null.
*/
public List getValues(String name) {
return (List) this.map.get(name);
}
/* ====================================================================== */
/* OBJECT METHODS */
/* ====================================================================== */
/**
* Return the URL-encoded {@link String} representation of this
* {@link Parameters Parameters} instance.
*/
public String toString() {
return this.string;
}
/**
* Return the URL-encoded {@link String} representation of this
* {@link Parameters Parameters} instance using the specified
* character encoding.
*/
public String toString(String encoding)
throws UnsupportedEncodingException {
StringBuffer buffer = new StringBuffer();
for (int x = 0; x < this.parameters.length; x ++) {
buffer.append(this.delimiter);
buffer.append(this.parameters[x].toString(encoding));
}
return buffer.substring(1);
}
/**
* Return the hash code value of this
* {@link Parameters Parameters} instance.
*/
public int hashCode() {
return this.string.hashCode();
}
/**
* Check if the specified {@link Object} is equal to this
* {@link Parameters Parameters} instance.
*
* The specified {@link Object} is considered equal to this one if
* it is non-null, it is a {@link Parameters Parameters}
* instance, and its {@link #toString() string representation} equals
* this one's.
*/
public boolean equals(Object object) {
if ((object != null) && (object instanceof Parameters)) {
return this.string.equals(((Parameters) object).string);
} else {
return false;
}
}
/* ====================================================================== */
/* PUBLIC INNER CLASSES */
/* ====================================================================== */
/**
* The {@link Parameters.Parameter Parameter} class represents a single
* parameter either parsed from a query string or a path element.
*
* @author Pier Fumagalli
*/
public static class Parameter implements Encodable {
/** The name of the parameter (decoded).
*/
private final String name;
/** The value of the parameter (decoded).
*/
private final String value;
/** The encoded {@link String} representation of this.
*/
private final String string;
/**
* Create a new {@link Parameters.Parameter Parameter} given an
* encoded parameter name and value.
*
* @throws NullPointerException if the name was null.
* @throws IllegalArgumentException if the name was an empty string.
*/
public Parameter(String name, String value) {
if (name == null) throw new NullPointerException();
if (name.length() == 0) throw new IllegalArgumentException();
this.name = name;
this.value = value;
this.string = EncodingTools.toString(this);
}
/* ================================================================== */
/* STATIC CONSTRUCTION METHODS */
/* ================================================================== */
/**
* Parse the specified parameters {@link String} into a
* {@link Parameters.Parameter} instance.
*
* @return a non-null and not empty {@link Parameters.Parameter}
* instance or null if the specified string was
* null or empty.
*/
public static Parameter parse(String parameter)
throws UnsupportedEncodingException {
try {
return parse(parameter, DEFAULT_ENCODING);
} catch (UnsupportedEncodingException exception) {
final String message = "Unsupported encoding " + DEFAULT_ENCODING;
final InternalError error = new InternalError(message);
throw (InternalError) error.initCause(exception);
}
}
/**
* Parse the specified parameters {@link String} into a
* {@link Parameters.Parameter} instance.
*
* @return a non-null and not empty {@link Parameters.Parameter}
* instance or null if the specified string was
* null or empty.
*/
public static Parameter parse(String parameter, String encoding)
throws UnsupportedEncodingException {
if (parameter == null) return null;
if (encoding == null) encoding = DEFAULT_ENCODING;
String split[] = StringTools.splitOnce(parameter, '=', false);
if (split[0] == null) return null;
return new Parameter(split[0], split[1]);
}
/* ================================================================== */
/* PUBLIC EXPOSED METHODS */
/* ================================================================== */
/**
* Return the URL-decoded name of this
* {@link Parameters.Parameter Parameter} instance.
*/
public String getName() {
return this.name;
}
/**
* Return the URL-decoded value of this
* {@link Parameters.Parameter Parameter} instance.
*/
public String getValue() {
return this.value;
}
/* ================================================================== */
/* OBJECT METHODS */
/* ================================================================== */
/**
* Return the URL-encoded {@link String} representation of this
* {@link Parameters.Parameter Parameter} instance.
*/
public String toString() {
return this.string;
}
/**
* Return the URL-encoded {@link String} representation of this
* {@link Parameters.Parameter Parameter} instance using the specified
* character encoding.
*/
public String toString(String encoding)
throws UnsupportedEncodingException {
if (this.value != null) {
return EncodingTools.urlEncode(this.name, encoding) + "=" +
EncodingTools.urlEncode(this.value, encoding);
} else {
return EncodingTools.urlEncode(this.name, encoding);
}
}
/**
* Return the hash code value for this
* {@link Parameters.Parameter Parameter} instance.
*/
public int hashCode() {
return this.string.hashCode();
}
/**
* Check if the specified {@link Object} is equal to this
* {@link Parameters.Parameter Parameter} instance.
*
* The specified {@link Object} is considered equal to this one if
* it is non-null, it is a {@link Parameters.Parameter Parameter}
* instance, and its {@link #toString() string representation} equals
* this one's.
*/
public boolean equals(Object object) {
if ((object != null) && (object instanceof Parameter)) {
return this.string.equals(((Parameter) object).string);
} else {
return false;
}
}
}
}