All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nustaq.serialization.FSTClazzLineageInfo Maven / Gradle / Ivy

Go to download

A fast java serialization drop in-replacement and some serialization based utils such as Structs and OffHeap Memory.

There is a newer version: 3.0.4-jdk17
Show newest version
package org.nustaq.serialization;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Represents a ordered class lineage based on the specificity of classes, where specificity is defined as follows:
 * 
 * 
  • null has specificity 0
  • *
  • java.lang.Object has specificity 0
  • *
  • an interface without any extends clause has specificity 1
  • *
  • a class or interface has a specificity of 1 + the specificity of the superclass + the sum of the specificity of the implemented interfaces.
  • *
    * @author Odd Moeller 2017-03-08. */ public final class FSTClazzLineageInfo { private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; private static final LineageInfo OBJECT_LINEAGE_INFO = new LineageInfo(new LinkedHashSet>(Collections.singletonList(Object.class)), 0); private static final ConcurrentMap, LineageInfo> lineageInfos = new ConcurrentHashMap, LineageInfo>(); public static final Comparator SPECIFICITY_CLASS_COMPARATOR = new Comparator() { @Override public int compare(final Class c1, final Class c2) { return getLineageInfo(c2).specificity - getLineageInfo(c1).specificity; } }; private FSTClazzLineageInfo() {} /** * Returns the specificity of the specified class as defined above. */ public static int getSpecificity(final Class clazz) { if (clazz == null) return 0; final LineageInfo lineageInfo = FSTClazzLineageInfo.getLineageInfo(clazz); return lineageInfo == null ? 0 : lineageInfo.specificity; } /** * Returns the lineage of the specified class ordered by specificity (the class itself is at position 0 since it is most specific in its lineage). */ public static Class[] getLineage(final Class clazz) { final LineageInfo lineageInfo = getLineageInfo(clazz); return lineageInfo == null ? EMPTY_CLASS_ARRAY : lineageInfo.lineage.toArray(new Class[lineageInfo.lineage.size()]); } private static LineageInfo getLineageInfo(final Class clazz) { if (clazz == null) return null; else if (clazz.equals(Object.class)) return OBJECT_LINEAGE_INFO; final LineageInfo lineageInfo = lineageInfos.get(clazz); if (lineageInfo != null) { return lineageInfo; } int specificity = 1; final LinkedHashSet> ancestors = new LinkedHashSet>(); final Class sc = getSuperclass(clazz); final LineageInfo sl = getLineageInfo(sc); if (sl != null) { ancestors.addAll(sl.lineage); specificity += sl.specificity; } for (final Class i : getInterfaces(clazz)) { final LineageInfo il = getLineageInfo(i); if (il != null) { ancestors.removeAll(il.lineage); ancestors.addAll(il.lineage); specificity += il.specificity; } } final Class[] array = ancestors.toArray(new Class[ancestors.size()]); Arrays.sort(array, SPECIFICITY_CLASS_COMPARATOR); final LinkedHashSet> lineage = new LinkedHashSet>(array.length + 1); lineage.add(clazz); Collections.addAll(lineage, array); final LineageInfo result = new LineageInfo(lineage, specificity); lineageInfos.putIfAbsent(clazz, result); return result; } private static Class getSuperclass(final Class c) { if (c == null) return null; return c.getSuperclass(); } private static Class[] getInterfaces(final Class c) { if (c == null) return null; return c.getInterfaces(); } private static final class LineageInfo { private final LinkedHashSet> lineage; private final int specificity; private LineageInfo(final LinkedHashSet> lineage, final int specificity) { this.lineage = lineage; this.specificity = specificity; } } }




    © 2015 - 2024 Weber Informatics LLC | Privacy Policy