001package co.codewizards.cloudstore.ls.core.invoke;
002
003import java.util.Collections;
004import java.util.HashMap;
005import java.util.HashSet;
006import java.util.Iterator;
007import java.util.Map;
008import java.util.ServiceLoader;
009import java.util.Set;
010
011public class ForceNonTransientClassSet {
012
013        private final Set<Class<?>> forceNonTransientClasses;
014        private final Map<Class<?>, Boolean> class2ForceNonTransient = new HashMap<>();
015
016        private static class Holder {
017                public static ForceNonTransientClassSet instance = new ForceNonTransientClassSet();
018        }
019
020        private ForceNonTransientClassSet() {
021                Set<Class<?>> s = new HashSet<Class<?>>();
022
023                for (Iterator<ForceNonTransientAdvisor> it = ServiceLoader.load(ForceNonTransientAdvisor.class).iterator(); it.hasNext(); ) {
024                        final ForceNonTransientAdvisor advisor = it.next();
025                        final Class<?>[] classes = advisor.getForceNonTransientClasses();
026                        if (classes == null)
027                                throw new IllegalStateException("Implementation error: advisor.getForceNonTransientClasses() returned null! " + advisor.getClass().getName());
028
029                        for (Class<?> clazz : classes)
030                                s.add(clazz);
031                }
032
033                forceNonTransientClasses = Collections.unmodifiableSet(s);
034        }
035
036        public synchronized boolean isForceNonTransientClass(Class<?> clazz) {
037                Boolean result = class2ForceNonTransient.get(clazz);
038                if (result == null) {
039                        for (final Class<?> forceNonTransientClass : forceNonTransientClasses) {
040                                if (forceNonTransientClass.isAssignableFrom(clazz)) {
041                                        result = true;
042                                        break;
043                                }
044                        }
045                        if (result == null)
046                                result = false;
047
048                        class2ForceNonTransient.put(clazz, result);
049                }
050                return result;
051        }
052
053        public static ForceNonTransientClassSet getInstance() {
054                return Holder.instance;
055        }
056}