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

net.binis.codegen.discovery.Discoverer Maven / Gradle / Ivy

There is a newer version: 1.2.22
Show newest version
package net.binis.codegen.discovery;

/*-
 * #%L
 * code-generator
 * %%
 * Copyright (C) 2021 - 2024 Binis Belev
 * %%
 * 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.
 * #L%
 */

import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import net.binis.codegen.annotation.CodeConfiguration;
import net.binis.codegen.factory.CodeFactory;

import java.io.*;
import java.lang.annotation.Annotation;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import static net.binis.codegen.tools.Reflection.loadClass;

@Slf4j
public abstract class Discoverer {

    public static final String TEMPLATE = "template";
    public static final String CONFIG = "config";
    public static final String INIT = "init";
    protected static final String RESOURCE_PATH = "binis/annotations";

    protected static List loadResources(
            final String name, final ClassLoader classLoader) throws IOException {
        var list = new ArrayList();
        var systemResources =
                (classLoader == null ? ClassLoader.getSystemClassLoader() : classLoader)
                        .getResources(name);
        while (systemResources.hasMoreElements()) {
            list.add(systemResources.nextElement().openStream());
        }
        return list;
    }

    public static List findAnnotations(String text) {
        var result = new ArrayList();
        Discoverer.processResource(text, result);
        return result;
    }

    public static List findAnnotations() {
        var result = new ArrayList();
        try {
            loadResources(RESOURCE_PATH, Discoverer.class.getClassLoader()).forEach(s -> Discoverer.processResource(s, result));
        } catch (Exception e) {
            log.error("Unable to discover services!", e);
        }
        return result;
    }

    protected static void processResource(String text, List services) {
        processResource(new BufferedReader(new StringReader(text)), services, false, false);
    }

    protected static void processResource(InputStream stream, List services) {
        processResource(new BufferedReader(new InputStreamReader(stream)), services, true, !(stream instanceof BufferedInputStream));
    }

    protected static void processResource(BufferedReader reader, List services, boolean tryLoad, boolean showWarning) {
        try {
            while (reader.ready()) {
                var line = reader.readLine();
                if (isNull(line)) {
                    break;
                }
                var parts = line.split(":");
                if (parts.length == 2) {
                    if (TEMPLATE.equals(parts[0])) {
                        if (tryLoad) {
                            var cls = loadClass(parts[1]);
                            if (nonNull(cls)) {
                                if (Annotation.class.isAssignableFrom(cls)) {
                                    services.add(DiscoveredService.builder().type(parts[0]).name(parts[1]).cls(cls).build());
                                }
                            } else {
                                if (showWarning) {
                                    log.warn("Can't load class: {}!", parts[1]);
                                }
                            }
                        } else {
                            services.add(DiscoveredService.builder().type(parts[0]).name(parts[1]).cls(null).build());
                        }
                    } else if (CONFIG.equals(parts[0])) {
                        if (tryLoad) {
                            var cls = loadClass(parts[1]);
                            if (nonNull(cls)) {
                                if (cls.isAnnotationPresent(CodeConfiguration.class)) {
                                    services.add(DiscoveredService.builder().type(parts[0]).name(parts[1]).cls(cls).build());
                                }
                            } else {
                                log.warn("Can't load class: {}!", parts[1]);
                            }
                        } else {
                            services.add(DiscoveredService.builder().type(parts[0]).name(parts[1]).cls(null).build());
                        }
                    } else if (INIT.equals(parts[0])) {
                        if (tryLoad) {
                            var cls = loadClass(parts[1]);
                            if (nonNull(cls)) {
                                CodeFactory.create(cls);
                                services.add(DiscoveredService.builder().type(parts[0]).name(parts[1]).cls(cls).build());
                            } else {
                                log.warn("Can't load class: {}!", parts[1]);
                            }
                        } else {
                            services.add(DiscoveredService.builder().type(parts[0]).name(parts[1]).cls(null).build());
                        }
                    } else {
                        Class cls = null;
                        if (tryLoad) {
                            cls = loadClass(parts[1]);
                        }
                        services.add(DiscoveredService.builder().type(parts[0]).name(parts[1]).cls(cls).build());
                    }
                } else {
                    log.warn("Invalid descriptor line: {}!", line);
                }
            }
        } catch (IOException e) {
            log.warn("Failed to process stream!", e);
        }
    }

    protected static Set readServiceFile(InputStream input) throws IOException {
        var serviceClasses = new HashSet();
        try (BufferedReader r = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8))) {
            String line;
            while ((line = r.readLine()) != null) {
                int commentStart = line.indexOf('#');
                if (commentStart >= 0) {
                    line = line.substring(0, commentStart);
                }
                line = line.trim();
                if (!line.isEmpty()) {
                    serviceClasses.add(line);
                }
            }
            return serviceClasses;
        }
    }

    @Builder
    @Data
    public static class DiscoveredService {
        protected String type;
        protected String name;
        protected Class cls;

        public boolean isConfig() {
            return CONFIG.equals(type);
        }

        public boolean isTemplate() {
            return TEMPLATE.equals(type);
        }

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy