001package org.javasimon.callback.logging;
002
003import org.javasimon.clock.SimonClock;
004
005/**
006 * Log template that logs something after every N milliseconds.
007 * The {@link #isEnabled(Object)} is only true after N milliseconds from the last log.
008 *
009 * @author gquintana
010 */
011public class PeriodicLogTemplate<C> extends DelegateLogTemplate<C> {
012
013        /** Maximum time between two calls to log method. */
014        private final long period;
015
016        /** Clock object used to get current time */
017        private final SimonClock clock;
018
019        /** Timestamp of next invocation. */
020        private long nextTime;
021
022        /**
023         * Constructor with other template and the required period in ms.
024         *
025         * @param delegate concrete log template
026         * @param period logging period in milliseconds
027         */
028        public PeriodicLogTemplate(LogTemplate<C> delegate, long period) {
029                this(delegate, period, SimonClock.SYSTEM);
030        }
031
032        public PeriodicLogTemplate(LogTemplate<C> delegate, long period, SimonClock clock) {
033                super(delegate);
034                this.period = period;
035                this.clock = clock;
036                initNextTime();
037        }
038
039
040        /**
041         * Get next invocation time time.
042         *
043         * @return next time
044         */
045        public long getNextTime() {
046                return nextTime;
047        }
048
049        /**
050         * Get current timestamp.
051         *
052         * @return current timestamp
053         */
054        long getCurrentTime() {
055                return clock.milliTime();
056        }
057
058        /** Computes the next timestamp. */
059        private synchronized void initNextTime() {
060                nextTime = getCurrentTime() + period;
061        }
062
063        /** Indicates whether next timestamp is in past. */
064        public synchronized boolean isNextTimePassed() {
065                return nextTime < getCurrentTime();
066        }
067
068        /**
069         * {@inheritDoc}
070         *
071         * @return true if delegate is true and enough time passed since last log
072         */
073        @Override
074        protected boolean isEnabled(C context) {
075                return super.isEnabled(context) && isNextTimePassed();
076        }
077
078        /**
079         * {@inheritDoc}
080         * <p/>
081         * Next time is updated after delegate log is called.
082         */
083        @Override
084        protected void log(String message) {
085                super.log(message);
086                initNextTime();
087        }
088}