001package org.javasimon.callback;
002
003import org.javasimon.Counter;
004import org.javasimon.CounterSample;
005import org.javasimon.Manager;
006import org.javasimon.Simon;
007import org.javasimon.Split;
008import org.javasimon.Stopwatch;
009import org.javasimon.StopwatchSample;
010
011import java.util.List;
012import java.util.concurrent.CopyOnWriteArrayList;
013
014/**
015 * Composite callbacks holds child-callbacks and delegates any operations to all of them.
016 * It implements {@link #callbacks()}, {@link #addCallback(Callback)} and {@link #removeCallback(Callback)}.
017 *
018 * @author <a href="mailto:virgo47@gmail.com">Richard "Virgo" Richter</a>
019 */
020public final class CompositeCallbackImpl implements CompositeCallback {
021
022        private List<Callback> callbacks = new CopyOnWriteArrayList<>();
023
024        private Manager manager; // not null indicates, that this callback is initialized (joined to manager)
025
026        /** Calls initialize on all children. */
027        @Override
028        public synchronized void initialize(Manager manager) {
029                if (this.manager != null) {
030                        throw new IllegalStateException("Callback was already initialized");
031                }
032                this.manager = manager;
033                for (Callback callback : callbacks) {
034                        try {
035                                callback.initialize(manager);
036                        } catch (Exception e) {
037                                onManagerWarning("Callback initialization error", e);
038                        }
039                }
040        }
041
042        /**
043         * Returns the list of all child-callbacks.
044         *
045         * @return children list
046         */
047        @Override
048        public List<Callback> callbacks() {
049                return callbacks;
050        }
051
052        /**
053         * Adds another callback as a child to this callback.
054         *
055         * @param callback added callback
056         */
057        @Override
058        public void addCallback(Callback callback) {
059                if (manager != null) {
060                        callback.initialize(manager);
061                }
062                callbacks.add(callback);
063        }
064
065        /**
066         * Removes specified callback from this callback, properly cleans up the removed callback.
067         *
068         * @param callback removed child-callback
069         */
070        @Override
071        public void removeCallback(Callback callback) {
072                callbacks.remove(callback);
073                if (manager != null) {
074                        callback.cleanup();
075                }
076        }
077
078        /** Removes specified callback from this callback, properly cleans up all the removed callbacks. */
079        @Override
080        public void removeAllCallbacks() {
081                for (Callback callback : callbacks) {
082                        removeCallback(callback);
083                }
084        }
085
086        /** Calls deactivate on all children. */
087        @Override
088        public void cleanup() {
089                manager = null;
090                for (Callback callback : callbacks) {
091                        try {
092                                callback.cleanup();
093                        } catch (Exception e) {
094                                onManagerWarning("Callback cleanup error", e);
095                        }
096                }
097        }
098
099        @Override
100        public void onStopwatchAdd(Stopwatch stopwatch, Split split, StopwatchSample sample) {
101                for (Callback callback : callbacks) {
102                        callback.onStopwatchAdd(stopwatch, split, sample);
103                }
104        }
105
106        @Override
107        public void onStopwatchStart(Split split) {
108                for (Callback callback : callbacks) {
109                        callback.onStopwatchStart(split);
110                }
111        }
112
113        @Override
114        public void onStopwatchStop(Split split, StopwatchSample sample) {
115                for (Callback callback : callbacks) {
116                        callback.onStopwatchStop(split, sample);
117                }
118        }
119
120        @Override
121        public void onCounterDecrease(Counter counter, long dec, CounterSample sample) {
122                for (Callback callback : callbacks) {
123                        callback.onCounterDecrease(counter, dec, sample);
124                }
125        }
126
127        @Override
128        public void onCounterIncrease(Counter counter, long inc, CounterSample sample) {
129                for (Callback callback : callbacks) {
130                        callback.onCounterIncrease(counter, inc, sample);
131                }
132        }
133
134        @Override
135        public void onCounterSet(Counter counter, long val, CounterSample sample) {
136                for (Callback callback : callbacks) {
137                        callback.onCounterSet(counter, val, sample);
138                }
139        }
140
141        @Override
142        public void onSimonCreated(Simon simon) {
143                for (Callback callback : callbacks) {
144                        callback.onSimonCreated(simon);
145                }
146        }
147
148        @Override
149        public void onSimonDestroyed(Simon simon) {
150                for (Callback callback : callbacks) {
151                        callback.onSimonDestroyed(simon);
152                }
153        }
154
155        @Override
156        public void onManagerClear() {
157                for (Callback callback : callbacks) {
158                        callback.onManagerClear();
159                }
160        }
161
162        @Override
163        public void onManagerMessage(String message) {
164                for (Callback callback : callbacks) {
165                        callback.onManagerMessage(message);
166                }
167        }
168
169        @Override
170        public void onManagerWarning(String warning, Exception cause) {
171                for (Callback callback : callbacks) {
172                        callback.onManagerWarning(warning, cause);
173                }
174        }
175}