001/*
002 * ====================================================================
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *   http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied.  See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 * ====================================================================
020 *
021 * This software consists of voluntary contributions made by many
022 * individuals on behalf of the Apache Software Foundation.  For more
023 * information on the Apache Software Foundation, please see
024 * <http://www.apache.org/>.
025 *
026 */
027
028package org.apache.http.message;
029
030import org.apache.http.HeaderElement;
031import org.apache.http.NameValuePair;
032import org.apache.http.util.Args;
033import org.apache.http.util.LangUtils;
034
035/**
036 * Basic implementation of {@link HeaderElement}
037 *
038 * @since 4.0
039 */
040public class BasicHeaderElement implements HeaderElement, Cloneable {
041
042    private final String name;
043    private final String value;
044    private final NameValuePair[] parameters;
045
046    /**
047     * Constructor with name, value and parameters.
048     *
049     * @param name header element name
050     * @param value header element value. May be {@code null}
051     * @param parameters header element parameters. May be {@code null}.
052     *   Parameters are copied by reference, not by value
053     */
054    public BasicHeaderElement(
055            final String name,
056            final String value,
057            final NameValuePair[] parameters) {
058        super();
059        this.name = Args.notNull(name, "Name");
060        this.value = value;
061        if (parameters != null) {
062            this.parameters = parameters;
063        } else {
064            this.parameters = new NameValuePair[] {};
065        }
066    }
067
068    /**
069     * Constructor with name and value.
070     *
071     * @param name header element name
072     * @param value header element value. May be {@code null}
073     */
074    public BasicHeaderElement(final String name, final String value) {
075       this(name, value, null);
076    }
077
078    @Override
079    public String getName() {
080        return this.name;
081    }
082
083    @Override
084    public String getValue() {
085        return this.value;
086    }
087
088    @Override
089    public NameValuePair[] getParameters() {
090        return this.parameters.clone();
091    }
092
093    @Override
094    public int getParameterCount() {
095        return this.parameters.length;
096    }
097
098    @Override
099    public NameValuePair getParameter(final int index) {
100        // ArrayIndexOutOfBoundsException is appropriate
101        return this.parameters[index];
102    }
103
104    @Override
105    public NameValuePair getParameterByName(final String name) {
106        Args.notNull(name, "Name");
107        NameValuePair found = null;
108        for (final NameValuePair current : this.parameters) {
109            if (current.getName().equalsIgnoreCase(name)) {
110                found = current;
111                break;
112            }
113        }
114        return found;
115    }
116
117    @Override
118    public boolean equals(final Object object) {
119        if (this == object) {
120            return true;
121        }
122        if (object instanceof HeaderElement) {
123            final BasicHeaderElement that = (BasicHeaderElement) object;
124            return this.name.equals(that.name)
125                && LangUtils.equals(this.value, that.value)
126                && LangUtils.equals(this.parameters, that.parameters);
127        } else {
128            return false;
129        }
130    }
131
132    @Override
133    public int hashCode() {
134        int hash = LangUtils.HASH_SEED;
135        hash = LangUtils.hashCode(hash, this.name);
136        hash = LangUtils.hashCode(hash, this.value);
137        for (final NameValuePair parameter : this.parameters) {
138            hash = LangUtils.hashCode(hash, parameter);
139        }
140        return hash;
141    }
142
143    @Override
144    public String toString() {
145        final StringBuilder buffer = new StringBuilder();
146        buffer.append(this.name);
147        if (this.value != null) {
148            buffer.append("=");
149            buffer.append(this.value);
150        }
151        for (final NameValuePair parameter : this.parameters) {
152            buffer.append("; ");
153            buffer.append(parameter);
154        }
155        return buffer.toString();
156    }
157
158    @Override
159    public Object clone() throws CloneNotSupportedException {
160        // parameters array is considered immutable
161        // no need to make a copy of it
162        return super.clone();
163    }
164
165}
166