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-2021 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

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); } @SuppressWarnings("ReferenceEquality") 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)Integer.parseInt(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); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy