001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      https://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.collections4.multiset;
018
019import java.util.Comparator;
020
021import org.apache.commons.collections4.Predicate;
022import org.apache.commons.collections4.SortedMultiSet;
023
024/**
025 * Decorates another {@link SortedMultiSet} to validate that additions
026 * match a specified predicate.
027 * <p>
028 * This multiset exists to provide validation for the decorated multiset.
029 * It is normally created to decorate an empty multiset.
030 * If an object cannot be added to the multiset, an {@link IllegalArgumentException}
031 * is thrown.
032 * </p>
033 * <p>
034 * One usage would be to ensure that no null entries are added to the multiset.
035 * </p>
036 * <pre>
037 * SortedMultiSet&lt;E&gt; set =
038 *      PredicatedSortedMultiSet.predicatedSortedMultiSet(new TreeMultiSet&lt;E&gt;(),
039 *                                                        NotNullPredicate.notNullPredicate());
040 * </pre>
041 *
042 * @param <E> The type held in the multiset
043 * @since 4.6.0
044 */
045public class PredicatedSortedMultiSet<E> extends PredicatedMultiSet<E> implements SortedMultiSet<E> {
046
047    /** Serialization version */
048    private static final long serialVersionUID = 20260705L;
049
050    /**
051     * Factory method to create a predicated (validating) multiset.
052     * <p>
053     * If there are any elements already in the multiset being decorated, they
054     * are validated.
055     *
056     * @param <E> The type of the elements in the multiset
057     * @param multiset  The multiset to decorate, must not be null
058     * @param predicate  The predicate to use for validation, must not be null
059     * @return A new predicated SortedMultiSet
060     * @throws NullPointerException if multiset or predicate is null
061     * @throws IllegalArgumentException if the multiset contains invalid elements
062     */
063    public static <E> PredicatedSortedMultiSet<E> predicatedSortedMultiSet(final SortedMultiSet<E> multiset,
064                                                                           final Predicate<? super E> predicate) {
065        return new PredicatedSortedMultiSet<>(multiset, predicate);
066    }
067
068    /**
069     * Constructor that wraps (not copies).
070     * <p>
071     * If there are any elements already in the multiset being decorated, they
072     * are validated.
073     * </p>
074     *
075     * @param multiset  The multiset to decorate, must not be null
076     * @param predicate  The predicate to use for validation, must not be null
077     * @throws NullPointerException if multiset or predicate is null
078     * @throws IllegalArgumentException if the multiset contains invalid elements
079     */
080    protected PredicatedSortedMultiSet(final SortedMultiSet<E> multiset, final Predicate<? super E> predicate) {
081        super(multiset, predicate);
082    }
083
084    @Override
085    public Comparator<? super E> comparator() {
086        return decorated().comparator();
087    }
088
089    /**
090     * Gets the decorated sorted multiset.
091     *
092     * @return The decorated multiset
093     */
094    @Override
095    protected SortedMultiSet<E> decorated() {
096        return (SortedMultiSet<E>) super.decorated();
097    }
098
099    @Override
100    public E first() {
101        return decorated().first();
102    }
103
104    @Override
105    public E last() {
106        return decorated().last();
107    }
108
109}