1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.spi;
18
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Iterator;
22 import java.util.List;
23
24 import org.apache.logging.log4j.ThreadContext.ContextStack;
25
26
27
28
29 public class MutableThreadContextStack implements ThreadContextStack {
30
31 private static final long serialVersionUID = 50505011L;
32
33
34
35
36 private final List<String> list;
37 private boolean frozen;
38
39
40
41
42 public MutableThreadContextStack() {
43 this(new ArrayList<String>());
44 }
45
46 public MutableThreadContextStack(final List<String> list) {
47 this.list = new ArrayList<String>(list);
48 }
49
50 private MutableThreadContextStack(final MutableThreadContextStack stack) {
51 this.list = new ArrayList<String>(stack.list);
52 }
53
54 private void checkInvariants() {
55 if (frozen) {
56 throw new UnsupportedOperationException("context stack has been frozen");
57 }
58 }
59
60 @Override
61 public String pop() {
62 checkInvariants();
63 if (list.isEmpty()) {
64 return null;
65 }
66 final int last = list.size() - 1;
67 final String result = list.remove(last);
68 return result;
69 }
70
71 @Override
72 public String peek() {
73 if (list.isEmpty()) {
74 return null;
75 }
76 final int last = list.size() - 1;
77 return list.get(last);
78 }
79
80 @Override
81 public void push(final String message) {
82 checkInvariants();
83 list.add(message);
84 }
85
86 @Override
87 public int getDepth() {
88 return list.size();
89 }
90
91 @Override
92 public List<String> asList() {
93 return list;
94 }
95
96 @Override
97 public void trim(final int depth) {
98 checkInvariants();
99 if (depth < 0) {
100 throw new IllegalArgumentException("Maximum stack depth cannot be negative");
101 }
102 if (list == null) {
103 return;
104 }
105 final List<String> copy = new ArrayList<String>(list.size());
106 final int count = Math.min(depth, list.size());
107 for (int i = 0; i < count; i++) {
108 copy.add(list.get(i));
109 }
110 list.clear();
111 list.addAll(copy);
112 }
113
114 @Override
115 public ThreadContextStack copy() {
116 return new MutableThreadContextStack(this);
117 }
118
119 @Override
120 public void clear() {
121 checkInvariants();
122 list.clear();
123 }
124
125 @Override
126 public int size() {
127 return list.size();
128 }
129
130 @Override
131 public boolean isEmpty() {
132 return list.isEmpty();
133 }
134
135 @Override
136 public boolean contains(final Object o) {
137 return list.contains(o);
138 }
139
140 @Override
141 public Iterator<String> iterator() {
142 return list.iterator();
143 }
144
145 @Override
146 public Object[] toArray() {
147 return list.toArray();
148 }
149
150 @Override
151 public <T> T[] toArray(final T[] ts) {
152 return list.toArray(ts);
153 }
154
155 @Override
156 public boolean add(final String s) {
157 checkInvariants();
158 return list.add(s);
159 }
160
161 @Override
162 public boolean remove(final Object o) {
163 checkInvariants();
164 return list.remove(o);
165 }
166
167 @Override
168 public boolean containsAll(final Collection<?> objects) {
169 return list.containsAll(objects);
170 }
171
172 @Override
173 public boolean addAll(final Collection<? extends String> strings) {
174 checkInvariants();
175 return list.addAll(strings);
176 }
177
178 @Override
179 public boolean removeAll(final Collection<?> objects) {
180 checkInvariants();
181 return list.removeAll(objects);
182 }
183
184 @Override
185 public boolean retainAll(final Collection<?> objects) {
186 checkInvariants();
187 return list.retainAll(objects);
188 }
189
190 @Override
191 public String toString() {
192 return String.valueOf(list);
193 }
194
195 @Override
196 public int hashCode() {
197 final int prime = 31;
198 int result = 1;
199 result = prime * result + ((this.list == null) ? 0 : this.list.hashCode());
200 return result;
201 }
202
203 @Override
204 public boolean equals(final Object obj) {
205 if (this == obj) {
206 return true;
207 }
208 if (obj == null) {
209 return false;
210 }
211 if (!(obj instanceof ThreadContextStack)) {
212 return false;
213 }
214 final ThreadContextStack other = (ThreadContextStack) obj;
215 final List<String> otherAsList = other.asList();
216 if (this.list == null) {
217 if (otherAsList != null) {
218 return false;
219 }
220 } else if (!this.list.equals(otherAsList)) {
221 return false;
222 }
223 return true;
224 }
225
226 @Override
227 public ContextStack getImmutableStackOrNull() {
228 return copy();
229 }
230
231
232
233
234 public void freeze() {
235 frozen = true;
236 }
237
238 public boolean isFrozen() {
239 return frozen;
240 }
241 }