001/*
002 * This file is part of the JDrupes non-blocking HTTP Codec
003 * Copyright (C) 2017 Michael N. Lipp
004 *
005 * This program is free software; you can redistribute it and/or modify it 
006 * under the terms of the GNU Lesser General Public License as published
007 * by the Free Software Foundation; either version 3 of the License, or 
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful, but 
011 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
012 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
013 * License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public License along 
016 * with this program; if not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.jdrupes.httpcodec.types;
020
021import java.net.HttpCookie;
022import java.util.Collection;
023import java.util.Iterator;
024import java.util.LinkedHashMap;
025import java.util.Optional;
026import java.util.stream.Stream;
027
028import org.jdrupes.httpcodec.types.Converters.SameSiteAttribute;
029
030/**
031 * Represents a list of cookies. The additional property "same site attribute"
032 * controls the generation of header fields.
033 */
034public class CookieList implements Iterable<HttpCookie> {
035
036    private LinkedHashMap<String, HttpCookie> cookies;
037    private final SameSiteAttribute sameSiteAttribute;
038
039    /**
040     * Creates a new empty cookie list with the specified same-site
041     * attribute.
042     */
043    public CookieList(SameSiteAttribute sameSiteAttribute) {
044        cookies = new LinkedHashMap<>();
045        this.sameSiteAttribute = sameSiteAttribute;
046    }
047
048    /**
049     * Creates a new empty cookie list.
050     */
051    public CookieList() {
052        this(SameSiteAttribute.UNSET);
053    }
054
055    /**
056     * Creates a new list with items copied from the existing collection.
057     * 
058     * @param existing the existing collection
059     */
060    public CookieList(Collection<HttpCookie> existing) {
061        this();
062        for (HttpCookie cookie : existing) {
063            cookies.put(cookie.getName(), cookie);
064        }
065    }
066
067    /**
068     * Returns the same site attribute passed to the constructor.
069     *
070     * @return the same site attribute
071     */
072    public SameSiteAttribute sameSiteAttribute() {
073        return sameSiteAttribute;
074    }
075
076    /**
077     * Returns the value for the cookie with the given name.
078     * 
079     * @param name the name
080     * @return the value if a cookie with the given name exists
081     */
082    public Optional<String> valueForName(String name) {
083        return Optional.ofNullable(cookies.get(name))
084            .map(HttpCookie::getValue);
085    }
086
087    /**
088     * Adds a cookie to the list. If a cookie with the same name
089     * already exists, it is replaced.
090     * 
091     * @param cookie the cookie
092     * @return the cookie list for easy chaining
093     */
094    public CookieList add(HttpCookie cookie) {
095        cookies.remove(cookie.getName());
096        cookies.put(cookie.getName(), cookie);
097        return this;
098    }
099
100    /**
101     * Removes all cookies from the list.
102     * 
103     * @return the cookie list for easy chaining
104     */
105    public CookieList clear() {
106        cookies.clear();
107        return this;
108    }
109
110    public boolean isEmpty() {
111        return cookies.isEmpty();
112    }
113
114    /*
115     * (non-Javadoc)
116     * 
117     * @see java.util.List#iterator()
118     */
119    @Override
120    public Iterator<HttpCookie> iterator() {
121        return cookies.values().iterator();
122    }
123
124    public Stream<HttpCookie> stream() {
125        return cookies.values().stream();
126    }
127
128    /**
129     * Remove the cookie with the given name.
130     * 
131     * @param name
132     * @return the cookie list for easy chaining
133     */
134    public boolean remove(String name) {
135        return false;
136    }
137
138    public int size() {
139        return cookies.size();
140    }
141
142}