All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jetty.util.Fields Maven / Gradle / Ivy

There is a newer version: 12.0.13
Show newest version
//
//  ========================================================================
//  Copyright (c) 1995-2013 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.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
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 case-insensitive name string 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 Map fields; /** *

Creates an empty modifiable {@link Fields} instance.

* @see #Fields(Fields, boolean) */ public Fields() { 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) { 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; return fields.equals(that.fields); } @Override public int hashCode() { return fields.hashCode(); } /** * @return a set of field names */ public Set names() { Set result = new LinkedHashSet<>(); for (Field field : fields.values()) result.add(field.name()); return result; } /** * @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(name.trim().toLowerCase(Locale.ENGLISH)); } /** *

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) { name = name.trim(); // Preserve the case for the field name Field field = new Field(name, value); fields.put(name.toLowerCase(Locale.ENGLISH), field); } /** *

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

* * @param field the field to put */ public void put(Field field) { if (field != null) fields.put(field.name().toLowerCase(Locale.ENGLISH), 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) { name = name.trim(); Field field = fields.get(name.toLowerCase(Locale.ENGLISH)); if (field == null) { field = new Field(name, value); fields.put(name.toLowerCase(Locale.ENGLISH), field); } else { field = new Field(field.name(), field.values(), value); fields.put(name.toLowerCase(Locale.ENGLISH), 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) { name = name.trim(); return fields.remove(name.toLowerCase(Locale.ENGLISH)); } /** *

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 size() { 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 String[] values; private Field(String name, String value) { this(name, new String[]{value}); } private Field(String name, String[] values, String... moreValues) { this.name = name; this.values = new String[values.length + moreValues.length]; System.arraycopy(values, 0, this.values, 0, values.length); System.arraycopy(moreValues, 0, this.values, values.length, moreValues.length); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Field that = (Field)obj; // Field names must be lowercase, thus we lowercase them before transmission, but keep them as is // internally. That's why we've to compare them case insensitive. return name.equalsIgnoreCase(that.name) && Arrays.equals(values, that.values); } @Override public int hashCode() { int result = name.toLowerCase(Locale.ENGLISH).hashCode(); result = 31 * result + Arrays.hashCode(values); return result; } /** * @return the field's name */ public String name() { return name; } /** * @return the first field's value */ public String value() { return values[0]; } /** *

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

* * @return the result of {@link #value()} converted to an integer, or null * @throws NumberFormatException if the conversion fails */ public Integer valueAsInt() { final String value = value(); return value == null ? null : Integer.valueOf(value); } /** * @return the field's values */ public String[] values() { return values; } /** * @return whether the field has multiple values */ public boolean hasMultipleValues() { return values.length > 1; } @Override public String toString() { return Arrays.toString(values); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy