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.lang.util.StringUtils;
022import org.apache.shiro.web.servlet.ProxiedFilterChain;
023
024import javax.servlet.Filter;
025import javax.servlet.FilterChain;
026import java.util.ArrayList;
027import java.util.Collection;
028import java.util.Iterator;
029import java.util.List;
030import java.util.ListIterator;
031
032/**
033 * Simple {@code NamedFilterList} implementation that is supported by a backing {@link List} instance and a simple
034 * {@link #getName() name} property. All {@link List} method implementations are immediately delegated to the
035 * wrapped backing list.
036 *
037 * @since 1.0
038 */
039public class SimpleNamedFilterList implements NamedFilterList {
040
041    private String name;
042    private List<Filter> backingList;
043
044    /**
045     * Creates a new {@code SimpleNamedFilterList} instance with the specified {@code name}, defaulting to a new
046     * {@link ArrayList ArrayList} instance as the backing list.
047     *
048     * @param name the name to assign to this instance.
049     * @throws IllegalArgumentException if {@code name} is null or empty.
050     */
051    public SimpleNamedFilterList(String name) {
052        this(name, new ArrayList<Filter>());
053    }
054
055    /**
056     * Creates a new {@code SimpleNamedFilterList} instance with the specified {@code name} and {@code backingList}.
057     *
058     * @param name        the name to assign to this instance.
059     * @param backingList the list instance used to back all of this class's {@link List} method implementations.
060     * @throws IllegalArgumentException if {@code name} is null or empty.
061     * @throws NullPointerException     if the backing list is {@code null}.
062     */
063    public SimpleNamedFilterList(String name, List<Filter> backingList) {
064        if (backingList == null) {
065            throw new NullPointerException("backingList constructor argument cannot be null.");
066        }
067        this.backingList = backingList;
068        setName(name);
069    }
070
071    protected void setName(String name) {
072        if (!StringUtils.hasText(name)) {
073            throw new IllegalArgumentException("Cannot specify a null or empty name.");
074        }
075        this.name = name;
076    }
077
078    public String getName() {
079        return name;
080    }
081
082    public FilterChain proxy(FilterChain orig) {
083        return new ProxiedFilterChain(orig, this);
084    }
085
086    public boolean add(Filter filter) {
087        return this.backingList.add(filter);
088    }
089
090    public void add(int index, Filter filter) {
091        this.backingList.add(index, filter);
092    }
093
094    public boolean addAll(Collection<? extends Filter> c) {
095        return this.backingList.addAll(c);
096    }
097
098    public boolean addAll(int index, Collection<? extends Filter> c) {
099        return this.backingList.addAll(index, c);
100    }
101
102    public void clear() {
103        this.backingList.clear();
104    }
105
106    public boolean contains(Object o) {
107        return this.backingList.contains(o);
108    }
109
110    public boolean containsAll(Collection<?> c) {
111        return this.backingList.containsAll(c);
112    }
113
114    public Filter get(int index) {
115        return this.backingList.get(index);
116    }
117
118    public int indexOf(Object o) {
119        return this.backingList.indexOf(o);
120    }
121
122    public boolean isEmpty() {
123        return this.backingList.isEmpty();
124    }
125
126    public Iterator<Filter> iterator() {
127        return this.backingList.iterator();
128    }
129
130    public int lastIndexOf(Object o) {
131        return this.backingList.lastIndexOf(o);
132    }
133
134    public ListIterator<Filter> listIterator() {
135        return this.backingList.listIterator();
136    }
137
138    public ListIterator<Filter> listIterator(int index) {
139        return this.backingList.listIterator(index);
140    }
141
142    public Filter remove(int index) {
143        return this.backingList.remove(index);
144    }
145
146    public boolean remove(Object o) {
147        return this.backingList.remove(o);
148    }
149
150    public boolean removeAll(Collection<?> c) {
151        return this.backingList.removeAll(c);
152    }
153
154    public boolean retainAll(Collection<?> c) {
155        return this.backingList.retainAll(c);
156    }
157
158    public Filter set(int index, Filter filter) {
159        return this.backingList.set(index, filter);
160    }
161
162    public int size() {
163        return this.backingList.size();
164    }
165
166    public List<Filter> subList(int fromIndex, int toIndex) {
167        return this.backingList.subList(fromIndex, toIndex);
168    }
169
170    public Object[] toArray() {
171        return this.backingList.toArray();
172    }
173
174    public <T> T[] toArray(T[] a) {
175        //noinspection SuspiciousToArrayCall
176        return this.backingList.toArray(a);
177    }
178}