From 17d8ffe18170c422ac2c6dccef8361e1ca684548 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 14 Feb 2022 21:30:25 -0800 Subject: Extract package scanning --- src/main/java/org/traccar/ServerManager.java | 48 ++----------- src/main/java/org/traccar/helper/ClassScanner.java | 80 ++++++++++++++++++++++ 2 files changed, 84 insertions(+), 44 deletions(-) create mode 100644 src/main/java/org/traccar/helper/ClassScanner.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index 0db786bdb..2e2cf7cff 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -18,23 +18,16 @@ package org.traccar; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Keys; +import org.traccar.helper.ClassScanner; -import java.io.File; import java.io.IOException; import java.net.BindException; import java.net.ConnectException; -import java.net.URI; import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; public class ServerManager { @@ -43,38 +36,9 @@ public class ServerManager { private final List connectorList = new LinkedList<>(); private final Map protocolList = new ConcurrentHashMap<>(); - private void loadPackage(String packageName) throws IOException, URISyntaxException, ReflectiveOperationException { - - List names = new LinkedList<>(); - String packagePath = packageName.replace('.', '/'); - URL packageUrl = getClass().getClassLoader().getResource(packagePath); - - if (packageUrl.getProtocol().equals("jar")) { - String jarFileName = URLDecoder.decode(packageUrl.getFile(), StandardCharsets.UTF_8.name()); - try (JarFile jf = new JarFile(jarFileName.substring(5, jarFileName.indexOf("!")))) { - Enumeration jarEntries = jf.entries(); - while (jarEntries.hasMoreElements()) { - String entryName = jarEntries.nextElement().getName(); - if (entryName.startsWith(packagePath) && entryName.length() > packagePath.length() + 5) { - names.add(entryName.substring(packagePath.length() + 1, entryName.lastIndexOf('.'))); - } - } - } - } else { - File folder = new File(new URI(packageUrl.toString())); - File[] files = folder.listFiles(); - if (files != null) { - for (File actual: files) { - String entryName = actual.getName(); - names.add(entryName.substring(0, entryName.lastIndexOf('.'))); - } - } - } - - for (String name : names) { - Class protocolClass = Class.forName(packageName + '.' + name); - if (BaseProtocol.class.isAssignableFrom(protocolClass) && Context.getConfig().hasKey( - Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(protocolClass)))) { + public ServerManager() throws IOException, URISyntaxException, ReflectiveOperationException { + for (Class protocolClass : ClassScanner.findSubclasses(BaseProtocol.class, "org.traccar.protocol")) { + if (Context.getConfig().hasKey(Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(protocolClass)))) { BaseProtocol protocol = (BaseProtocol) protocolClass.getDeclaredConstructor().newInstance(); connectorList.addAll(protocol.getConnectorList()); protocolList.put(protocol.getName(), protocol); @@ -82,10 +46,6 @@ public class ServerManager { } } - public ServerManager() throws IOException, URISyntaxException, ReflectiveOperationException { - loadPackage("org.traccar.protocol"); - } - public BaseProtocol getProtocol(String name) { return protocolList.get(name); } diff --git a/src/main/java/org/traccar/helper/ClassScanner.java b/src/main/java/org/traccar/helper/ClassScanner.java new file mode 100644 index 000000000..c928f6a12 --- /dev/null +++ b/src/main/java/org/traccar/helper/ClassScanner.java @@ -0,0 +1,80 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.helper; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.Enumeration; +import java.util.LinkedList; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +public final class ClassScanner { + + private ClassScanner() { + } + + public static List> findSubclasses( + Class baseClass) throws IOException, URISyntaxException, ReflectiveOperationException { + return findSubclasses(baseClass, baseClass.getPackageName()); + } + + public static List> findSubclasses(Class baseClass, String packageName) + throws IOException, URISyntaxException, ReflectiveOperationException { + + List names = new LinkedList<>(); + String packagePath = packageName.replace('.', '/'); + URL packageUrl = baseClass.getClassLoader().getResource(packagePath); + + if (packageUrl.getProtocol().equals("jar")) { + String jarFileName = URLDecoder.decode(packageUrl.getFile(), StandardCharsets.UTF_8.name()); + try (JarFile jf = new JarFile(jarFileName.substring(5, jarFileName.indexOf("!")))) { + Enumeration jarEntries = jf.entries(); + while (jarEntries.hasMoreElements()) { + String entryName = jarEntries.nextElement().getName(); + if (entryName.startsWith(packagePath) && entryName.length() > packagePath.length() + 5) { + names.add(entryName.substring(packagePath.length() + 1, entryName.lastIndexOf('.'))); + } + } + } + } else { + File folder = new File(new URI(packageUrl.toString())); + File[] files = folder.listFiles(); + if (files != null) { + for (File actual: files) { + String entryName = actual.getName(); + names.add(entryName.substring(0, entryName.lastIndexOf('.'))); + } + } + } + + var classes = new LinkedList>(); + for (String name : names) { + var clazz = Class.forName(packageName + '.' + name); + if (baseClass.isAssignableFrom(clazz)) { + classes.add(clazz); + } + } + return classes; + } + +} -- cgit v1.2.3