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 org.apache.log4j.helpers.NullEnumeration;
020    import org.apache.log4j.spi.LoggerFactory;
021    import org.apache.log4j.spi.LoggingEvent;
022    import org.apache.logging.log4j.core.LoggerContext;
023    import org.apache.logging.log4j.core.helpers.NameUtil;
024    import org.apache.logging.log4j.message.LocalizedMessage;
025    import org.apache.logging.log4j.message.Message;
026    import org.apache.logging.log4j.message.ObjectMessage;
027    
028    import java.util.Enumeration;
029    import java.util.Map;
030    import java.util.ResourceBundle;
031    import java.util.WeakHashMap;
032    import java.util.concurrent.ConcurrentHashMap;
033    import java.util.concurrent.ConcurrentMap;
034    
035    
036    /**
037     * Implementation of the Category class for compatibility, despite it having been deprecated a long, long time ago.
038     */
039    public class Category {
040    
041        private static LoggerFactory loggerFactory = new PrivateFactory();
042    
043        private static final Map<LoggerContext, ConcurrentMap<String, Logger>> CONTEXT_MAP =
044            new WeakHashMap<LoggerContext, ConcurrentMap<String, Logger>>();
045    
046        private static final String FQCN = Category.class.getName();
047    
048        /**
049         * Resource bundle for localized messages.
050         */
051        protected ResourceBundle bundle = null;
052    
053        private final org.apache.logging.log4j.core.Logger logger;
054    
055        /**
056         * Constructor used by Logger to specify a LoggerContext.
057         * @param context The LoggerContext.
058         * @param name The name of the Logger.
059         */
060        protected Category(LoggerContext context, String name) {
061            this.logger = context.getLogger(name);
062        }
063    
064        /**
065         * Constructor exposed by Log4j 1.2.
066         * @param name The name of the Logger.
067         */
068        protected Category(String name) {
069            this((LoggerContext) PrivateManager.getContext(), name);
070        }
071    
072        private Category(org.apache.logging.log4j.core.Logger logger) {
073            this.logger = logger;
074        }
075    
076        public static Category getInstance(String name) {
077            return getInstance((LoggerContext) PrivateManager.getContext(), name, loggerFactory);
078        }
079    
080        static Category getInstance(LoggerContext context, String name) {
081            return getInstance(context, name, loggerFactory);
082        }
083    
084        static Category getInstance(LoggerContext context, String name, LoggerFactory factory) {
085            ConcurrentMap<String, Logger> loggers = getLoggersMap(context);
086            Logger logger = loggers.get(name);
087            if (logger != null) {
088                return logger;
089            }
090            logger = factory.makeNewLoggerInstance(context, name);
091            Logger prev = loggers.putIfAbsent(name, logger);
092            return prev == null ? logger : prev;
093        }
094    
095        public static Category getInstance(Class clazz) {
096            return getInstance(clazz.getName());
097        }
098    
099        static Category getInstance(LoggerContext context, Class clazz) {
100            return getInstance(context, clazz.getName());
101        }
102    
103        public final String getName() {
104            return logger.getName();
105        }
106    
107        org.apache.logging.log4j.core.Logger getLogger() {
108            return logger;
109        }
110    
111        public final Category getParent() {
112            org.apache.logging.log4j.core.Logger parent = logger.getParent();
113            if (parent == null) {
114                return null;
115            }
116            ConcurrentMap<String, Logger> loggers = getLoggersMap(logger.getContext());
117            Logger l = loggers.get(parent.getName());
118            return l == null ? new Category(parent) : l;
119        }
120    
121        public static Category getRoot() {
122            return getInstance("");
123        }
124    
125    
126        static Category getRoot(LoggerContext context) {
127            return getInstance(context, "");
128        }
129    
130        private static ConcurrentMap<String, Logger> getLoggersMap(LoggerContext context) {
131            synchronized (CONTEXT_MAP) {
132                ConcurrentMap<String, Logger> map = CONTEXT_MAP.get(context);
133                if (map == null) {
134                    map = new ConcurrentHashMap<String, Logger>();
135                    CONTEXT_MAP.put(context, map);
136                }
137                return map;
138            }
139        }
140    
141        /**
142         Returns all the currently defined categories in the default
143         hierarchy as an {@link java.util.Enumeration Enumeration}.
144    
145         <p>The root category is <em>not</em> included in the returned
146         {@link Enumeration}.
147    
148         @deprecated Please use {@link LogManager#getCurrentLoggers()} instead.
149         */
150        public static Enumeration getCurrentCategories() {
151            return LogManager.getCurrentLoggers();
152        }
153    
154        public final Level getEffectiveLevel() {
155            org.apache.logging.log4j.Level level = logger.getLevel();
156    
157            switch (level) {
158                case TRACE:
159                    return Level.TRACE;
160                case DEBUG:
161                    return Level.DEBUG;
162                case INFO:
163                    return Level.INFO;
164                case WARN:
165                    return Level.WARN;
166                default:
167                    return Level.ERROR;
168            }
169        }
170    
171        public final Priority getChainedPriority() {
172            return getEffectiveLevel();
173        }
174    
175        public final Level getLevel() {
176            return getEffectiveLevel();
177        }
178    
179        public void setLevel(Level level) {
180            logger.setLevel(org.apache.logging.log4j.Level.toLevel(level.levelStr));
181        }
182    
183        public final Level getPriority() {
184            return getEffectiveLevel();
185        }
186    
187        public void setPriority(Priority priority) {
188            logger.setLevel(org.apache.logging.log4j.Level.toLevel(priority.levelStr));
189        }
190    
191        public void debug(Object message) {
192            maybeLog(FQCN, org.apache.logging.log4j.Level.DEBUG, message, null);
193        }
194    
195        public void debug(Object message, Throwable t) {
196            maybeLog(FQCN, org.apache.logging.log4j.Level.DEBUG, message, t);
197        }
198    
199        public boolean isDebugEnabled() {
200            return logger.isDebugEnabled();
201        }
202    
203        public void error(Object message) {
204            maybeLog(FQCN, org.apache.logging.log4j.Level.ERROR, message, null);
205        }
206    
207        public void error(Object message, Throwable t) {
208            maybeLog(FQCN, org.apache.logging.log4j.Level.ERROR, message, t);
209        }
210    
211        public boolean isErrorEnabled() {
212            return logger.isErrorEnabled();
213        }
214    
215        public void warn(Object message) {
216            maybeLog(FQCN, org.apache.logging.log4j.Level.WARN, message, null);
217        }
218    
219        public void warn(Object message, Throwable t) {
220            maybeLog(FQCN, org.apache.logging.log4j.Level.WARN, message, t);
221        }
222    
223        public boolean isWarnEnabled() {
224            return logger.isWarnEnabled();
225        }
226    
227        public void fatal(Object message) {
228            maybeLog(FQCN, org.apache.logging.log4j.Level.FATAL, message, null);
229        }
230    
231        public void fatal(Object message, Throwable t) {
232            maybeLog(FQCN, org.apache.logging.log4j.Level.FATAL, message, t);
233        }
234    
235        public boolean isFatalEnabled() {
236            return logger.isFatalEnabled();
237        }
238    
239        public void info(Object message) {
240            maybeLog(FQCN, org.apache.logging.log4j.Level.INFO, message, null);
241        }
242    
243        public void info(Object message, Throwable t) {
244            maybeLog(FQCN, org.apache.logging.log4j.Level.INFO, message, t);
245        }
246    
247        public boolean isInfoEnabled() {
248            return logger.isInfoEnabled();
249        }
250    
251        public void trace(Object message) {
252            maybeLog(FQCN, org.apache.logging.log4j.Level.TRACE, message, null);
253        }
254    
255        public void trace(Object message, Throwable t) {
256            maybeLog(FQCN, org.apache.logging.log4j.Level.TRACE, message, t);
257        }
258    
259        public boolean isTraceEnabled() {
260            return logger.isTraceEnabled();
261        }
262    
263        public boolean isEnabledFor(Priority level) {
264            org.apache.logging.log4j.Level lvl = org.apache.logging.log4j.Level.toLevel(level.toString());
265            return isEnabledFor(lvl);
266        }
267    
268        /**
269         * No-op implementation.
270         * @param appender The Appender to add.
271         */
272        public void addAppender(Appender appender) {
273        }
274    
275        /**
276         * No-op implementation.
277         * @param event The logging event.
278         */
279        public void callAppenders(LoggingEvent event) {
280        }
281    
282        public Enumeration getAllAppenders() {
283            return NullEnumeration.getInstance();
284        }
285    
286        /**
287         * No-op implementation.
288         * @param name The name of the Appender.
289         * @return null.
290         */
291        public Appender getAppender(String name) {
292            return null;
293        }
294    
295        /**
296         Is the appender passed as parameter attached to this category?
297         @param appender The Appender to add.
298         */
299        public boolean isAttached(Appender appender) {
300            return false;
301        }
302    
303        /**
304         * No-op implementation.
305         */
306        public void removeAllAppenders() {
307        }
308    
309        /**
310         * No-op implementation.
311         * @param appender The Appender to remove.
312         */
313        public void removeAppender(Appender appender) {
314        }
315    
316        /**
317         * No-op implementation.
318         * @param name The Appender to remove.
319         */
320        public void removeAppender(String name) {
321        }
322    
323        /**
324         * No-op implementation.
325         */
326        public static void shutdown() {
327        }
328    
329    
330        public void forcedLog(String fqcn, Priority level, Object message, Throwable t) {
331            org.apache.logging.log4j.Level lvl = org.apache.logging.log4j.Level.toLevel(level.toString());
332            Message msg = message instanceof Message ? (Message) message : new ObjectMessage(message);
333            logger.log(null, fqcn, lvl, msg, t);
334        }
335    
336        public boolean exists(String name) {
337            return PrivateManager.getContext().hasLogger(name);
338        }
339    
340        public boolean getAdditivity() {
341            return logger.isAdditive();
342        }
343    
344        public void setAdditivity(boolean additivity) {
345            logger.setAdditive(additivity);
346        }
347    
348        public void setResourceBundle(ResourceBundle bundle) {
349            this.bundle = bundle;
350        }
351    
352        public ResourceBundle getResourceBundle() {
353            if (bundle != null) {
354                return bundle;
355            }
356            int i = 0;
357            String name = logger.getName();
358            ConcurrentMap<String, Logger> loggers = getLoggersMap(logger.getContext());
359            while ((name = NameUtil.getSubName(name)) != null) {
360                if (loggers.containsKey(name)) {
361                    ResourceBundle rb = loggers.get(name).bundle;
362                    if (rb != null) {
363                        return rb;
364                    }
365                }
366            }
367            return null;
368        }
369    
370        /**
371         If <code>assertion</code> parameter is {@code false}, then
372         logs <code>msg</code> as an {@link #error(Object) error} statement.
373    
374         <p>The <code>assert</code> method has been renamed to
375         <code>assertLog</code> because <code>assert</code> is a language
376         reserved word in JDK 1.4.
377    
378         @param assertion The assertion.
379         @param msg The message to print if <code>assertion</code> is
380         false.
381    
382         @since 1.2
383         */
384        public void assertLog(boolean assertion, String msg) {
385            if (!assertion) {
386                this.error(msg);
387            }
388        }
389    
390        public void l7dlog(Priority priority, String key, Throwable t) {
391            if (isEnabledFor(priority)) {
392                Message msg = new LocalizedMessage(bundle, key, null);
393                forcedLog(FQCN, priority, msg, t);
394            }
395        }
396    
397        public void l7dlog(Priority priority, String key, Object[] params, Throwable t) {
398            if (isEnabledFor(priority)) {
399                Message msg = new LocalizedMessage(bundle, key, params);
400                forcedLog(FQCN, priority, msg, t);
401            }
402        }
403    
404        public void log(Priority priority, Object message, Throwable t) {
405            if (isEnabledFor(priority)) {
406                Message msg = new ObjectMessage(message);
407                forcedLog(FQCN, priority, msg, t);
408            }
409        }
410    
411        public void log(Priority priority, Object message) {
412            if (isEnabledFor(priority)) {
413                Message msg = new ObjectMessage(message);
414                forcedLog(FQCN, priority, msg, null);
415            }
416        }
417    
418        public void log(String fqcn, Priority priority, Object message, Throwable t) {
419            if (isEnabledFor(priority)) {
420                Message msg = new ObjectMessage(message);
421                forcedLog(fqcn, priority, msg, t);
422            }
423        }
424    
425        private void maybeLog(String fqcn, org.apache.logging.log4j.Level level,
426                Object message, Throwable throwable) {
427            if (logger.isEnabled(level, null, message, throwable)) {
428                logger.log(null, FQCN, level, new ObjectMessage(message), throwable);
429            }
430        }
431    
432        /**
433         * Private logger factory.
434         */
435        private static class PrivateFactory implements LoggerFactory {
436    
437            public Logger makeNewLoggerInstance(LoggerContext context, String name) {
438                return new Logger(context, name);
439            }
440        }
441    
442        /**
443         * Private LogManager.
444         */
445        private static class PrivateManager extends org.apache.logging.log4j.LogManager {
446            private static final String FQCN = Category.class.getName();
447    
448            public static org.apache.logging.log4j.spi.LoggerContext getContext() {
449                return getContext(FQCN, false);
450            }
451    
452            public static org.apache.logging.log4j.Logger getLogger(String name) {
453                return getLogger(FQCN, name);
454            }
455        }
456    
457        private boolean isEnabledFor(org.apache.logging.log4j.Level level) {
458            return logger.isEnabled(level, null, null);
459        }
460    
461    }