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