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}