CE-1887 Move methods deal with getting classes from packages into new ClassPathUtils

This commit is contained in:
2024-10-17 12:22:58 -05:00
parent 9ea92553e7
commit eb754b42b9
2 changed files with 89 additions and 54 deletions

View File

@ -22,7 +22,6 @@
package com.kingsrook.qqq.backend.core.model.metadata;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
@ -30,14 +29,12 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.ClassPath;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.logging.QLogger;
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppMetaData;
import com.kingsrook.qqq.backend.core.utils.ClassPathUtils;
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
@ -51,8 +48,6 @@ public class MetaDataProducerHelper
private static Map<Class<?>, Integer> comparatorValuesByType = new HashMap<>();
private static Integer defaultComparatorValue;
private static ImmutableSet<ClassPath.ClassInfo> topLevelClasses;
static
{
////////////////////////////////////////////////////////////////////////////////////////
@ -87,7 +82,7 @@ public class MetaDataProducerHelper
////////////////////////////////////////////////////////////////////////
// find all the meta data producer classes in (and under) the package //
////////////////////////////////////////////////////////////////////////
classesInPackage = getClassesInPackage(packageName);
classesInPackage = ClassPathUtils.getClassesInPackage(packageName);
}
catch(Exception e)
{
@ -176,51 +171,4 @@ public class MetaDataProducerHelper
}
/*******************************************************************************
** from https://stackoverflow.com/questions/520328/can-you-find-all-classes-in-a-package-using-reflection
** (since the original, from ChatGPT, didn't work in jars, despite GPT hallucinating that it would)
*******************************************************************************/
private static List<Class<?>> getClassesInPackage(String packageName) throws IOException
{
List<Class<?>> classes = new ArrayList<>();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
for(ClassPath.ClassInfo info : getTopLevelClasses(loader))
{
if(info.getName().startsWith(packageName))
{
classes.add(info.load());
}
}
return (classes);
}
/*******************************************************************************
**
*******************************************************************************/
private static ImmutableSet<ClassPath.ClassInfo> getTopLevelClasses(ClassLoader loader) throws IOException
{
if(topLevelClasses == null)
{
topLevelClasses = ClassPath.from(loader).getTopLevelClasses();
}
return (topLevelClasses);
}
/*******************************************************************************
**
*******************************************************************************/
public static void clearTopLevelClassCache()
{
topLevelClasses = null;
}
}

View File

@ -0,0 +1,87 @@
/*
* QQQ - Low-code Application Framework for Engineers.
* Copyright (C) 2021-2024. Kingsrook, LLC
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
* contact@kingsrook.com
* https://github.com/Kingsrook/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.kingsrook.qqq.backend.core.utils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.ClassPath;
/*******************************************************************************
** Utilities for reading classes - e.g., finding all in a package
*******************************************************************************/
@SuppressWarnings("ALL") // the api we're using here, from google, is marked Beta
public class ClassPathUtils
{
private static ImmutableSet<ClassPath.ClassInfo> topLevelClasses;
/*******************************************************************************
** from https://stackoverflow.com/questions/520328/can-you-find-all-classes-in-a-package-using-reflection
**
*******************************************************************************/
public static List<Class<?>> getClassesInPackage(String packageName) throws IOException
{
List<Class<?>> classes = new ArrayList<>();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
for(ClassPath.ClassInfo info : getTopLevelClasses(loader))
{
if(info.getName().startsWith(packageName))
{
classes.add(info.load());
}
}
return (classes);
}
/*******************************************************************************
**
*******************************************************************************/
private static ImmutableSet<ClassPath.ClassInfo> getTopLevelClasses(ClassLoader loader) throws IOException
{
if(topLevelClasses == null)
{
topLevelClasses = ClassPath.from(loader).getTopLevelClasses();
}
return (topLevelClasses);
}
/*******************************************************************************
**
*******************************************************************************/
public static void clearTopLevelClassCache()
{
topLevelClasses = null;
}
}