package org.infinispan.marshall.core; import java.io.Serializable; import java.util.ArrayList; import java.util.List; /** * As much as possible, Infinispan consumers should provide * {@link org.infinispan.commons.marshall.Externalizer} or * {@link org.infinispan.commons.marshall.AdvancedExternalizer} instances * for the types being marshalled, so that these types can be marshalled * as efficiently as possible. * * Sometimes however, Infinispan consumers might rely on the fact * that a certain type implements Java's standard {@link Serializable} * or {@link java.io.Externalizable}. * * This class acts a test barrier which controls, provided assertions * have been enabled, which types can be externally marshalled using * JBoss Marshalling. * * The plan is for external marshalling is be morphed into user type * marshalling, at which point this class won't be used any more. * * @since 9.0 */ public final class ExternallyMarshallable { private static final List<String> whiteListClasses = new ArrayList<>(); static { whiteListClasses.add("Exception"); whiteListClasses.add("$$Lambda$"); whiteListClasses.add("java.lang.Class"); whiteListClasses.add("java.time.Instant"); // prod whiteListClasses.add("org.hibernate.search.query.engine.impl.LuceneHSQuery"); // prod whiteListClasses.add("org.infinispan.distexec.RunnableAdapter"); // prod whiteListClasses.add("org.infinispan.jcache.annotation.DefaultCacheKey"); // prod whiteListClasses.add("org.infinispan.query.clustered.QueryResponse"); // prod whiteListClasses.add("org.infinispan.server.core.transport.NettyTransport$ConnectionAdderTask"); // prod whiteListClasses.add("org.infinispan.server.hotrod.CheckAddressTask"); // prod whiteListClasses.add("org.infinispan.server.infinispan.task.DistributedServerTask"); // prod whiteListClasses.add("org.infinispan.scripting.impl.DataType"); // prod whiteListClasses.add("org.infinispan.scripting.impl.DistributedScript"); whiteListClasses.add("org.infinispan.stats.impl.ClusterCacheStatsImpl$DistributedCacheStatsCallable"); // prod whiteListClasses.add("org.infinispan.xsite.BackupSender$TakeSiteOfflineResponse"); // prod whiteListClasses.add("org.infinispan.xsite.BackupSender$BringSiteOnlineResponse"); // prod whiteListClasses.add("org.infinispan.xsite.XSiteAdminCommand$Status"); // prod whiteListClasses.add("org.infinispan.util.logging.events.EventLogLevel"); // prod whiteListClasses.add("org.infinispan.util.logging.events.EventLogCategory"); // prod whiteListClasses.add("java.util.Date"); // test whiteListClasses.add("java.lang.Byte"); // test whiteListClasses.add("java.lang.Integer"); // test whiteListClasses.add("java.lang.Double"); // test whiteListClasses.add("java.lang.Short"); // test whiteListClasses.add("java.lang.Long"); // test whiteListClasses.add("org.infinispan.test"); // test whiteListClasses.add("org.infinispan.server.test"); // test whiteListClasses.add("org.infinispan.it"); // test whiteListClasses.add("org.infinispan.all"); // test whiteListClasses.add("org.infinispan.query.api"); // test whiteListClasses.add("org.jboss.as.quickstarts.datagrid"); // quickstarts testing } private ExternallyMarshallable() { // Static class } /** * Adds package or class name to the externally marshallable white list. */ public static void addToWhiteList(String type) { whiteListClasses.add(type); } public static boolean isAllowed(Object obj) { Class<?> clazz = obj.getClass(); return isAllowed(clazz); } public static boolean isAllowed(Class<?> clazz) { Package pkg = clazz.getPackage(); if (pkg == null) { if (clazz.isArray()) { return true; } else { throw new IllegalStateException("No package info for " + clazz + ", runtime-generated class?"); } } String pkgName = pkg.getName(); boolean isBlackList = Serializable.class.isAssignableFrom(clazz) && isMarshallablePackage(pkgName) && !ExternalPojo.class.isAssignableFrom(clazz) && !isWhiteList(clazz.getName()); return !isBlackList; } private static boolean isMarshallablePackage(String pkg) { return pkg.startsWith("java.") || pkg.startsWith("org.infinispan.") || pkg.startsWith("org.jgroups.") || pkg.startsWith("org.apache") || pkg.startsWith("org.jboss") || pkg.startsWith("com.arjuna") ; } private static boolean isWhiteList(String className) { return whiteListClasses.stream().anyMatch(className::contains); } }