001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.shiro.web.filter.mgt;
020
021import org.apache.shiro.util.StringUtils;
022import org.apache.shiro.web.servlet.ProxiedFilterChain;
023
024import javax.servlet.Filter;
025import javax.servlet.FilterChain;
026import java.util.*;
027
028/**
029 * Simple {@code NamedFilterList} implementation that is supported by a backing {@link List} instance and a simple
030 * {@link #getName() name} property. All {@link List} method implementations are immediately delegated to the
031 * wrapped backing list.
032 *
033 * @since 1.0
034 */
035public class SimpleNamedFilterList implements NamedFilterList {
036
037    private String name;
038    private List<Filter> backingList;
039
040    /**
041     * Creates a new {@code SimpleNamedFilterList} instance with the specified {@code name}, defaulting to a new
042     * {@link ArrayList ArrayList} instance as the backing list.
043     *
044     * @param name the name to assign to this instance.
045     * @throws IllegalArgumentException if {@code name} is null or empty.
046     */
047    public SimpleNamedFilterList(String name) {
048        this(name, new ArrayList<Filter>());
049    }
050
051    /**
052     * Creates a new {@code SimpleNamedFilterList} instance with the specified {@code name} and {@code backingList}.
053     *
054     * @param name        the name to assign to this instance.
055     * @param backingList the list instance used to back all of this class's {@link List} method implementations.
056     * @throws IllegalArgumentException if {@code name} is null or empty.
057     * @throws NullPointerException     if the backing list is {@code null}.
058     */
059    public SimpleNamedFilterList(String name, List<Filter> backingList) {
060        if (backingList == null) {
061            throw new NullPointerException("backingList constructor argument cannot be null.");
062        }
063        this.backingList = backingList;
064        setName(name);
065    }
066
067    protected void setName(String name) {
068        if (!StringUtils.hasText(name)) {
069            throw new IllegalArgumentException("Cannot specify a null or empty name.");
070        }
071        this.name = name;
072    }
073
074    public String getName() {
075        return name;
076    }
077
078    public FilterChain proxy(FilterChain orig) {
079        return new ProxiedFilterChain(orig, this);
080    }
081
082    public boolean add(Filter filter) {
083        return this.backingList.add(filter);
084    }
085
086    public void add(int index, Filter filter) {
087        this.backingList.add(index, filter);
088    }
089
090    public boolean addAll(Collection<? extends Filter> c) {
091        return this.backingList.addAll(c);
092    }
093
094    public boolean addAll(int index, Collection<? extends Filter> c) {
095        return this.backingList.addAll(index, c);
096    }
097
098    public void clear() {
099        this.backingList.clear();
100    }
101
102    public boolean contains(Object o) {
103        return this.backingList.contains(o);
104    }
105
106    public boolean containsAll(Collection<?> c) {
107        return this.backingList.containsAll(c);
108    }
109
110    public Filter get(int index) {
111        return this.backingList.get(index);
112    }
113
114    public int indexOf(Object o) {
115        return this.backingList.indexOf(o);
116    }
117
118    public boolean isEmpty() {
119        return this.backingList.isEmpty();
120    }
121
122    public Iterator<Filter> iterator() {
123        return this.backingList.iterator();
124    }
125
126    public int lastIndexOf(Object o) {
127        return this.backingList.lastIndexOf(o);
128    }
129
130    public ListIterator<Filter> listIterator() {
131        return this.backingList.listIterator();
132    }
133
134    public ListIterator<Filter> listIterator(int index) {
135        return this.backingList.listIterator(index);
136    }
137
138    public Filter remove(int index) {
139        return this.backingList.remove(index);
140    }
141
142    public boolean remove(Object o) {
143        return this.backingList.remove(o);
144    }
145
146    public boolean removeAll(Collection<?> c) {
147        return this.backingList.removeAll(c);
148    }
149
150    public boolean retainAll(Collection<?> c) {
151        return this.backingList.retainAll(c);
152    }
153
154    public Filter set(int index, Filter filter) {
155        return this.backingList.set(index, filter);
156    }
157
158    public int size() {
159        return this.backingList.size();
160    }
161
162    public List<Filter> subList(int fromIndex, int toIndex) {
163        return this.backingList.subList(fromIndex, toIndex);
164    }
165
166    public Object[] toArray() {
167        return this.backingList.toArray();
168    }
169
170    public <T> T[] toArray(T[] a) {
171        //noinspection SuspiciousToArrayCall
172        return this.backingList.toArray(a);
173    }
174}