X-Git-Url: https://code.wpia.club/?p=gigi.git;a=blobdiff_plain;f=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Futil%2FFields.java;fp=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Futil%2FFields.java;h=152934de362a619d71f9bb0c8149fa7bdfba35f0;hp=0000000000000000000000000000000000000000;hb=73ef54a38e3930a1a789cdc6b5fa23cdd4c9d086;hpb=515007c7c1351045420669d65b59c08fa46850f2 diff --git a/lib/jetty/org/eclipse/jetty/util/Fields.java b/lib/jetty/org/eclipse/jetty/util/Fields.java new file mode 100644 index 00000000..152934de --- /dev/null +++ b/lib/jetty/org/eclipse/jetty/util/Fields.java @@ -0,0 +1,336 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +/** + *

A container for name/value pairs, known as fields.

+ *

A {@link Field} is composed of a name string that can be case-sensitive + * or case-insensitive (by specifying the option at the constructor) and + * of a case-sensitive set of value strings.

+ *

The implementation of this class is not thread safe.

+ */ +public class Fields implements Iterable +{ + private final boolean caseSensitive; + private final Map fields; + + /** + *

Creates an empty, modifiable, case insensitive {@link Fields} instance.

+ * @see #Fields(Fields, boolean) + */ + public Fields() + { + this(false); + } + + /** + *

Creates an empty, modifiable, case insensitive {@link Fields} instance.

+ * @param caseSensitive whether this {@link Fields} instance must be case sensitive + * @see #Fields(Fields, boolean) + */ + public Fields(boolean caseSensitive) + { + this.caseSensitive = caseSensitive; + fields = new LinkedHashMap<>(); + } + + /** + *

Creates a {@link Fields} instance by copying the fields from the given + * {@link Fields} and making it (im)mutable depending on the given {@code immutable} parameter

+ * + * @param original the {@link Fields} to copy fields from + * @param immutable whether this instance is immutable + */ + public Fields(Fields original, boolean immutable) + { + this.caseSensitive = original.caseSensitive; + Map copy = new LinkedHashMap<>(); + copy.putAll(original.fields); + fields = immutable ? Collections.unmodifiableMap(copy) : copy; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + Fields that = (Fields)obj; + if (getSize() != that.getSize()) + return false; + if (caseSensitive != that.caseSensitive) + return false; + for (Map.Entry entry : fields.entrySet()) + { + String name = entry.getKey(); + Field value = entry.getValue(); + if (!value.equals(that.get(name), caseSensitive)) + return false; + } + return true; + } + + @Override + public int hashCode() + { + return fields.hashCode(); + } + + /** + * @return a set of field names + */ + public Set getNames() + { + Set result = new LinkedHashSet<>(); + for (Field field : fields.values()) + result.add(field.getName()); + return result; + } + + private String normalizeName(String name) + { + return caseSensitive ? name : name.toLowerCase(Locale.ENGLISH); + } + + /** + * @param name the field name + * @return the {@link Field} with the given name, or null if no such field exists + */ + public Field get(String name) + { + return fields.get(normalizeName(name)); + } + + /** + *

Inserts or replaces the given name/value pair as a single-valued {@link Field}.

+ * + * @param name the field name + * @param value the field value + */ + public void put(String name, String value) + { + // Preserve the case for the field name + Field field = new Field(name, value); + fields.put(normalizeName(name), field); + } + + /** + *

Inserts or replaces the given {@link Field}, mapped to the {@link Field#getName() field's name}

+ * + * @param field the field to put + */ + public void put(Field field) + { + if (field != null) + fields.put(normalizeName(field.getName()), field); + } + + /** + *

Adds the given value to a field with the given name, + * creating a {@link Field} is none exists for the given name.

+ * + * @param name the field name + * @param value the field value to add + */ + public void add(String name, String value) + { + String key = normalizeName(name); + Field field = fields.get(key); + if (field == null) + { + // Preserve the case for the field name + field = new Field(name, value); + fields.put(key, field); + } + else + { + field = new Field(field.getName(), field.getValues(), value); + fields.put(key, field); + } + } + + /** + *

Removes the {@link Field} with the given name

+ * + * @param name the name of the field to remove + * @return the removed field, or null if no such field existed + */ + public Field remove(String name) + { + return fields.remove(normalizeName(name)); + } + + /** + *

Empties this {@link Fields} instance from all fields

+ * @see #isEmpty() + */ + public void clear() + { + fields.clear(); + } + + /** + * @return whether this {@link Fields} instance is empty + */ + public boolean isEmpty() + { + return fields.isEmpty(); + } + + /** + * @return the number of fields + */ + public int getSize() + { + return fields.size(); + } + + /** + * @return an iterator over the {@link Field}s present in this instance + */ + @Override + public Iterator iterator() + { + return fields.values().iterator(); + } + + @Override + public String toString() + { + return fields.toString(); + } + + /** + *

A named list of string values.

+ *

The name is case-sensitive and there must be at least one value.

+ */ + public static class Field + { + private final String name; + private final List values; + + public Field(String name, String value) + { + this(name, Collections.singletonList(value)); + } + + private Field(String name, List values, String... moreValues) + { + this.name = name; + List list = new ArrayList<>(values.size() + moreValues.length); + list.addAll(values); + list.addAll(Arrays.asList(moreValues)); + this.values = Collections.unmodifiableList(list); + } + + public boolean equals(Field that, boolean caseSensitive) + { + if (this == that) + return true; + if (that == null) + return false; + if (caseSensitive) + return equals(that); + return name.equalsIgnoreCase(that.name) && values.equals(that.values); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + Field that = (Field)obj; + return name.equals(that.name) && values.equals(that.values); + } + + @Override + public int hashCode() + { + int result = name.hashCode(); + result = 31 * result + values.hashCode(); + return result; + } + + /** + * @return the field's name + */ + public String getName() + { + return name; + } + + /** + * @return the first field's value + */ + public String getValue() + { + return values.get(0); + } + + /** + *

Attempts to convert the result of {@link #getValue()} to an integer, + * returning it if the conversion is successful; returns null if the + * result of {@link #getValue()} is null.

+ * + * @return the result of {@link #getValue()} converted to an integer, or null + * @throws NumberFormatException if the conversion fails + */ + public Integer getValueAsInt() + { + final String value = getValue(); + return value == null ? null : Integer.valueOf(value); + } + + /** + * @return the field's values + */ + public List getValues() + { + return values; + } + + /** + * @return whether the field has multiple values + */ + public boolean hasMultipleValues() + { + return values.size() > 1; + } + + @Override + public String toString() + { + return String.format("%s=%s", name, values); + } + } +}