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.logging.log4j.core.async;
018    
019    import org.apache.logging.log4j.status.StatusLogger;
020    
021    /**
022     * Factory for {@code Clock} objects.
023     */
024    public final class ClockFactory {
025    
026        /**
027         * Name of the system property that can be used to specify a {@code Clock}
028         * implementation class.
029         */
030        public static final String PROPERTY_NAME = "AsyncLogger.Clock";
031        private static final StatusLogger LOGGER = StatusLogger.getLogger();
032    
033        // private static final Clock clock = createClock();
034    
035        private ClockFactory() {
036        }
037    
038        /**
039         * Returns a {@code Clock} instance depending on the value of system
040         * property {@code "AsyncLogger.Clock"}.
041         * <p>
042         * If system property {@code AsyncLogger.Clock=CachedClock} is specified,
043         * this method returns an instance of {@link CachedClock}. If system
044         * property {@code AsyncLogger.Clock=CoarseCachedClock} is specified, this
045         * method returns an instance of {@link CoarseCachedClock}.
046         * <p>
047         * If another value is specified, this value is taken as the fully qualified
048         * class name of a class that implements the {@code Clock} interface. An
049         * object of this class is instantiated and returned.
050         * <p>
051         * If no value is specified, or if the specified value could not correctly
052         * be instantiated or did not implement the {@code Clock} interface, then an
053         * instance of {@link SystemClock} is returned.
054         * 
055         * @return a {@code Clock} instance
056         */
057        public static Clock getClock() {
058            return createClock();
059        }
060    
061        private static Clock createClock() {
062            String userRequest = System.getProperty(PROPERTY_NAME);
063            if (userRequest == null || "SystemClock".equals(userRequest)) {
064                LOGGER.debug("Using default SystemClock for timestamps");
065                return new SystemClock();
066            }
067            if (CachedClock.class.getName().equals(userRequest) //
068                    || "CachedClock".equals(userRequest)) {
069                LOGGER.debug("Using specified CachedClock for timestamps");
070                return CachedClock.instance();
071            }
072            if (CoarseCachedClock.class.getName().equals(userRequest) //
073                    || "CoarseCachedClock".equals(userRequest)) {
074                LOGGER.debug("Using specified CoarseCachedClock for timestamps");
075                return CoarseCachedClock.instance();
076            }
077            try {
078                Clock result = (Clock) Class.forName(userRequest).newInstance();
079                LOGGER.debug("Using {} for timestamps", userRequest);
080                return result;
081            } catch (Exception e) {
082                String fmt = "Could not create {}: {}, using default SystemClock for timestamps";
083                LOGGER.error(fmt, userRequest, e);
084                return new SystemClock();
085            }
086        }
087    }