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.log4j;
018    
019    import java.util.Stack;
020    
021    /**
022     *
023     */
024    public final class NDC {
025    
026        private NDC() {
027        }
028    
029        /**
030         * Clear any nested diagnostic information if any. This method is
031         * useful in cases where the same thread can be potentially used
032         * over and over in different unrelated contexts.
033         * <p>
034         * This method is equivalent to calling the {@link #setMaxDepth}
035         * method with a zero <code>maxDepth</code> argument.
036         * </p>
037         */
038        public static void clear() {
039            org.apache.logging.log4j.ThreadContext.clearStack();
040        }
041    
042    
043        /**
044         * Clone the diagnostic context for the current thread.
045         * <p>
046         * Internally a diagnostic context is represented as a stack.  A
047         * given thread can supply the stack (i.e. diagnostic context) to a
048         * child thread so that the child can inherit the parent thread's
049         * diagnostic context.
050         * </p>
051         * <p>
052         * The child thread uses the {@link #inherit inherit} method to
053         * inherit the parent's diagnostic context.
054         * </p>
055         * @return Stack A clone of the current thread's  diagnostic context.
056         */
057        @SuppressWarnings("rawtypes")
058        public static Stack cloneStack() {
059            final Stack<String> stack = new Stack<String>();
060            for (final String element : org.apache.logging.log4j.ThreadContext.cloneStack().asList()) {
061                stack.push(element);
062            }
063            return stack;
064        }
065    
066    
067        /**
068         * Inherit the diagnostic context of another thread.
069         * <p>
070         * The parent thread can obtain a reference to its diagnostic
071         * context using the {@link #cloneStack} method.  It should
072         * communicate this information to its child so that it may inherit
073         * the parent's diagnostic context.
074         * </p>
075         * <p>
076         * The parent's diagnostic context is cloned before being
077         * inherited. In other words, once inherited, the two diagnostic
078         * contexts can be managed independently.
079         * </p>
080         * <p>
081         * In java, a child thread cannot obtain a reference to its
082         * parent, unless it is directly handed the reference. Consequently,
083         * there is no client-transparent way of inheriting diagnostic
084         * contexts. Do you know any solution to this problem?
085         * </p>
086         * @param stack The diagnostic context of the parent thread.
087         */
088        public static void inherit(final Stack<String> stack) {
089            org.apache.logging.log4j.ThreadContext.setStack(stack);
090        }
091    
092    
093        /**
094         * <strong style="color:#FF4040">Never use this method directly.</strong>
095         *
096         * @return The string value of the specified key.
097         */
098        public static String get() {
099            return org.apache.logging.log4j.ThreadContext.peek();
100        }
101    
102        /**
103         * Get the current nesting depth of this diagnostic context.
104         * @return int The number of elements in the call stack.
105         * @see #setMaxDepth
106         */
107        public static int getDepth() {
108            return org.apache.logging.log4j.ThreadContext.getDepth();
109        }
110    
111        /**
112         * Clients should call this method before leaving a diagnostic
113         * context.
114         * <p>
115         * The returned value is the value that was pushed last. If no
116         * context is available, then the empty string "" is returned.
117         * </p>
118         * @return String The innermost diagnostic context.
119         */
120        public static String pop() {
121            return org.apache.logging.log4j.ThreadContext.pop();
122        }
123    
124        /**
125         * Looks at the last diagnostic context at the top of this NDC
126         * without removing it.
127         * <p>
128         * The returned value is the value that was pushed last. If no
129         * context is available, then the empty string "" is returned.
130         * </p>
131         * @return String The innermost diagnostic context.
132         */
133        public static String peek() {
134            return org.apache.logging.log4j.ThreadContext.peek();
135        }
136    
137        /**
138         * Push new diagnostic context information for the current thread.
139         * <p>
140         * The contents of the <code>message</code> parameter is
141         * determined solely by the client.
142         * </p>
143         * @param message The new diagnostic context information.
144         */
145        public static void push(final String message) {
146            org.apache.logging.log4j.ThreadContext.push(message);
147        }
148    
149        /**
150         * Remove the diagnostic context for this thread.
151         * <p>
152         * Each thread that created a diagnostic context by calling
153         * {@link #push} should call this method before exiting. Otherwise,
154         * the memory used by the <b>thread</b> cannot be reclaimed by the
155         * VM.
156         * </p>
157         * <p>
158         * As this is such an important problem in heavy duty systems and
159         * because it is difficult to always guarantee that the remove
160         * method is called before exiting a thread, this method has been
161         * augmented to lazily remove references to dead threads. In
162         * practice, this means that you can be a little sloppy and
163         * occasionally forget to call {@code remove} before exiting a
164         * thread. However, you must call <code>remove</code> sometime. If
165         * you never call it, then your application is sure to run out of
166         * memory.
167         * </p>
168         */
169        public static void remove() {
170            org.apache.logging.log4j.ThreadContext.removeStack();
171        }
172    
173        /**
174         * Set maximum depth of this diagnostic context. If the current
175         * depth is smaller or equal to <code>maxDepth</code>, then no
176         * action is taken.
177         * <p>
178         * This method is a convenient alternative to multiple {@link
179         * #pop} calls. Moreover, it is often the case that at the end of
180         * complex call sequences, the depth of the NDC is
181         * unpredictable. The <code>setMaxDepth</code> method circumvents
182         * this problem.
183         * </p>
184         * <p>
185         * For example, the combination
186         * </p>
187         * <pre>
188         * void foo() {
189         * &nbsp;  int depth = NDC.getDepth();
190         *
191         * &nbsp;  ... complex sequence of calls
192         *
193         * &nbsp;  NDC.setMaxDepth(depth);
194         * }
195         * </pre>
196         * <p>
197         * ensures that between the entry and exit of foo the depth of the
198         * diagnostic stack is conserved.
199         * </p>
200         *
201         * @see #getDepth
202         * @param maxDepth The maximum depth of the stack.
203         */
204        public static void setMaxDepth(final int maxDepth) {
205            org.apache.logging.log4j.ThreadContext.trim(maxDepth);
206        }
207    }