001package co.codewizards.cloudstore.ls.core.invoke.refjanitor;
002
003import static co.codewizards.cloudstore.core.util.AssertUtil.*;
004
005import java.util.ArrayList;
006import java.util.Collections;
007import java.util.Comparator;
008import java.util.Iterator;
009import java.util.List;
010import java.util.ServiceLoader;
011
012import org.slf4j.Logger;
013import org.slf4j.LoggerFactory;
014
015import co.codewizards.cloudstore.ls.core.invoke.ObjectManager;
016import co.codewizards.cloudstore.ls.core.invoke.filter.ExtMethodInvocationRequest;
017
018public class ReferenceJanitorRegistry {
019
020        private static final Logger logger = LoggerFactory.getLogger(ReferenceJanitorRegistry.class);
021
022        private final ObjectManager objectManager;
023        private final List<ReferenceJanitor> referenceJanitors;
024
025        public ReferenceJanitorRegistry(final ObjectManager objectManager) {
026                this.objectManager = assertNotNull(objectManager, "objectManager");
027                referenceJanitors = loadReferenceJanitors();
028        }
029
030        private List<ReferenceJanitor> loadReferenceJanitors() {
031                final ArrayList<ReferenceJanitor> result = new ArrayList<>();
032
033                final Iterator<ReferenceJanitor> it = ServiceLoader.load(ReferenceJanitor.class).iterator();
034                while (it.hasNext())
035                        result.add(it.next());
036
037                Collections.sort(result, new Comparator<ReferenceJanitor>() {
038                        @Override
039                        public int compare(ReferenceJanitor o1, ReferenceJanitor o2) {
040                                int result = -1 * Integer.compare(o1.getPriority(), o2.getPriority());
041                                if (result != 0)
042                                        return result;
043
044                                return o1.getClass().getName().compareTo(o2.getClass().getName());
045                        }
046                });
047
048                result.trimToSize();
049                return result;
050        }
051
052        public void cleanUp() {
053                for (final ReferenceJanitor referenceJanitor : referenceJanitors) {
054                        try {
055                                referenceJanitor.cleanUp();
056                        } catch (Exception x) {
057                                logger.error("cleanUp: " + x, x);
058                        }
059                }
060        }
061
062        public void preInvoke(final ExtMethodInvocationRequest extMethodInvocationRequest) {
063                for (final ReferenceJanitor referenceJanitor : referenceJanitors) {
064                        try {
065                                referenceJanitor.preInvoke(extMethodInvocationRequest);
066                        } catch (Exception x) {
067                                logger.error("preInvoke: " + x, x);
068                        }
069                }
070        }
071
072        public void postInvoke(final ExtMethodInvocationRequest extMethodInvocationRequest, final Object resultObject, final Throwable error) {
073                for (final ReferenceJanitor referenceJanitor : referenceJanitors) {
074                        try {
075                                referenceJanitor.postInvoke(extMethodInvocationRequest, resultObject, error);
076                        } catch (Exception x) {
077                                logger.error("preInvoke: " + x, x);
078                        }
079                }
080        }
081}