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

net.n2oapp.properties.io.PropertiesInfoCollector Maven / Gradle / Ivy

There is a newer version: 7.28.1
Show newest version
package net.n2oapp.properties.io;

import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author V. Alexeev.
 */
public class PropertiesInfoCollector {

    private final static String GROUP_PREFIX = "##";
    private final static String NAME_PREFIX = "#";

    private final String locationPattern;
    private final String encode;
    private Map> data;
    private final AtomicBoolean init = new AtomicBoolean(false);

    public PropertiesInfoCollector(String locationPattern) {
        this.locationPattern = locationPattern;
        this.encode = "UTF-8";
    }

    public PropertiesInfoCollector(String encode, String locationPattern) {
        this.encode = encode;
        this.locationPattern = locationPattern;
    }

    public Map> getPropertyInfoMap() {
        lazyInit();
        return data;
    }

    public String getGroup(String property) {
        return getPropertyInfoMap().entrySet().stream()
                .filter(e -> e.getValue().stream().filter(p -> p.key.equals(property)).findFirst().isPresent())
                .findFirst().map(Map.Entry::getKey).orElse(null);
    }

    public PropertyInfo getInfo(String group, String key) {
        return group != null ? getPropertyInfoMap().getOrDefault(group, Collections.emptyList())
                .stream().filter(info -> info.key.equals(key)).findFirst().orElseGet(() -> new PropertyInfo(key)) : new PropertyInfo(key);
    }

    private void lazyInit() {
        if (!init.get()) {
            synchronized (init) {
                if (!init.get()) {
                    try {
                        data = calculate();
                    } catch (IOException e) {
                        throw new IllegalStateException(e);
                    }
                    init.set(true);
                }
            }
        }
    }

    private Map> calculate() throws IOException {
        Map> propertyMap = new HashMap<>();
        PathMatchingResourcePatternResolver pathPatternResolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = pathPatternResolver.getResources(locationPattern);
        if (resources == null || resources.length == 0) {
            return Collections.unmodifiableMap(new HashMap<>());
        }
        Arrays.stream(resources).map(this::retrieve)
                .forEach(file -> {
                    final String[] group = {""};
                    final String[] name = {null};
                    final String[] description = {""};
                    file.forEach(str -> {
                        for (String line : str.split("\n")) {
                            line = clean(line);
                            if (!line.isEmpty()) {
                                if (isGroup(line)) {
                                    group[0] = line.replaceFirst("##", "").trim();
                                } else if (name[0] == null && isNameOrDescription(line)) {
                                    name[0] = line;
                                } else if (name[0] != null && isNameOrDescription(line)) {
                                    description[0] = description[0].concat(line).concat("\n");
                                } else { //is val
                                    propertyMap.computeIfAbsent(group[0], key -> new ArrayList<>())
                                            .add(new PropertiesInfoCollector.PropertyInfo(getKey(line), group[0], name[0], description[0]));
                                    name[0] = null;
                                    description[0] = "";
                                }
                            }
                        }
                    });
                });

        Map> propertyMapNotModified = new ConcurrentHashMap<>();
        propertyMap.forEach((k, v) -> propertyMapNotModified.put(k, Collections.unmodifiableList(v)));
        return Collections.unmodifiableMap(propertyMapNotModified);
    }

    private List retrieve(Resource resource) {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), encode))) {
            List lines = new ArrayList<>();
            String str;
            while ((str = reader.readLine()) != null)
                lines.add(str.concat("\n"));
            return lines;
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    private boolean isGroup(String str) {
        return str.startsWith(GROUP_PREFIX);
    }

    private boolean isNameOrDescription(String str) {
        return str.startsWith(NAME_PREFIX);
    }

    private String getKey(String str) {
        return str.split("[\\s=]")[0];
    }

    private String clean(String str) {
        return str.replaceFirst("\\s*", "");
    }

    public static class PropertyInfo {
        public final String key;
        public final String group;
        public final String name;
        public final String description;

        public PropertyInfo(String key) {
            this.key = key;
            this.group = null;
            this.name = null;
            this.description = null;
        }

        public PropertyInfo(String key, String group, String name, String description) {
            this.key = key;
            this.group = group;
            this.name = name != null ? name.replaceFirst("#", "").trim() : null;
            this.description = description != null && !description.isEmpty() ?
                    description.replaceFirst("#", "").replaceAll("\\n#", "\n").replaceAll("\\s+", " ").trim() : null;
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy