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