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     *      http://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     */
017    package org.apache.logging.log4j.spi;
018    
019    import java.util.ArrayList;
020    import java.util.Collection;
021    import java.util.Iterator;
022    import java.util.List;
023    
024    /**
025     *
026     */
027    public class MutableThreadContextStack implements ThreadContextStack {
028    
029        private static final long serialVersionUID = 50505011L;
030    
031        /**
032         * The underlying list (never null).
033         */
034        private final List<String> list;
035    
036        public MutableThreadContextStack(List<String> list) {
037            this.list = new ArrayList<String>(list);
038        }
039    
040        private MutableThreadContextStack(MutableThreadContextStack stack) {
041            this.list = new ArrayList<String>(stack.list);
042        }
043    
044        public String pop() {
045            if (list.isEmpty()) {
046                return null;
047            }
048            final int last = list.size() - 1;
049            final String result = list.remove(last);
050            return result;
051        }
052    
053        public String peek() {
054            if (list.isEmpty()) {
055                return null;
056            }
057            final int last = list.size() - 1;
058            return list.get(last);
059        }
060    
061        public void push(final String message) {
062            list.add(message);
063        }
064    
065        public int getDepth() {
066            return list.size();
067        }
068    
069        public List<String> asList() {
070            return list;
071        }
072    
073        public void trim(final int depth) {
074            if (depth < 0) {
075                throw new IllegalArgumentException("Maximum stack depth cannot be negative");
076            }
077            if (list == null) {
078                return;
079            }
080            final List<String> copy = new ArrayList<String>(list.size());
081            int count = Math.min(depth, list.size());
082            for(int i = 0; i < count; i++) {
083                copy.add(list.get(i));
084            }
085            list.clear();
086            list.addAll(copy);
087        }
088    
089        public ThreadContextStack copy() {
090            return new MutableThreadContextStack(this);
091        }
092    
093        public void clear() {
094            list.clear();
095        }
096    
097        public int size() {
098            return list.size();
099        }
100    
101        public boolean isEmpty() {
102            return list.isEmpty();
103        }
104    
105        public boolean contains(Object o) {
106            return list.contains(o);
107        }
108    
109        public Iterator<String> iterator() {
110            return list.iterator();
111        }
112    
113        public Object[] toArray() {
114            return list.toArray();
115        }
116    
117        public <T> T[] toArray(T[] ts) {
118            return list.toArray(ts);
119        }
120    
121        public boolean add(String s) {
122            return list.add(s);
123        }
124    
125        public boolean remove(Object o) {
126            return list.remove(o);
127        }
128    
129        public boolean containsAll(Collection<?> objects) {
130            return list.containsAll(objects);
131        }
132    
133        public boolean addAll(Collection<? extends String> strings) {
134            return list.addAll(strings);
135        }
136    
137        public boolean removeAll(Collection<?> objects) {
138            return list.removeAll(objects);
139        }
140    
141        public boolean retainAll(Collection<?> objects) {
142            return list.retainAll(objects);
143        }
144    }