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

org.nuiton.jaxx.runtime.application.ApplicationResourceManager Maven / Gradle / Ivy

The newest version!
/*
 * #%L
 * JAXX :: Runtime
 * %%
 * Copyright (C) 2008 - 2024 Code Lutin, Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser 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 General Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */
package org.nuiton.jaxx.runtime.application;

import io.ultreia.java4all.util.SortedProperties;
import io.ultreia.java4all.util.Zips;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import io.ultreia.java4all.config.spi.ConfigOptionDef;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.TreeMap;

/**
 * La classe responsable du chargement de toutes les resources qui viennent de
 * l'application et qui seont ensuite redispatchés dans le répertoire de
 * resource de l'utilisateur.
 *
 * @author Tony Chemit - [email protected]
 * @since 1.4
 */
public class ApplicationResourceManager {

    private static final Logger log = LogManager.getLogger(ApplicationResourceManager.class);
    private final Map resourceDefinitions;
    private Map resources;

    public ApplicationResourceManager() {
        resourceDefinitions = new TreeMap<>();
    }

    public static URL getResource(String location) {
        URL resource = ApplicationResourceManager.class.getResource(location);
        try {
            // test que la resource existe bien dans le class-path
            try (InputStream in = openInternalStream(resource)) {
                log.debug("opening: " + in);
            }
            return resource;
        } catch (Exception e) {
            throw new IllegalStateException("Could not treat internal resource " + location);
        }
    }

    protected static InputStream openInternalStream(URL resource) {
        try {
            InputStream in = resource.openStream();
            Objects.requireNonNull(in, "Could not find internal resource " + resource);
            return in;
        } catch (Exception e) {
            throw new IllegalStateException("Could not treat internal resource " + resource);
        }
    }

    public void registerResource(Resource resource) {
        resourceDefinitions.put(resource.getLocation(), resource);
    }

    protected Map getResources() {
        if (resources == null) {
            resources = new TreeMap<>();
        }
        return resources;
    }

    public Properties getResourceProperties(String resource) throws IOException {
        URL url = getRegistredResource(resource).getUrl();
        return getResource(url);
    }

    private Properties getResource(URL url) throws IOException {

        String path = url.toString();

        Properties result = getResources().get(path);

        if (result == null) {

            result = load(url);
            log.debug("Store configuration [" + path + "]");
            getResources().put(path, result);
        }

        // toujours faire une copie pour eviter toute altération des
        // configuration par défaut.
        SortedProperties tmp = new SortedProperties();
        tmp.putAll(result);
        return tmp;
    }

    public Properties load(URL url) throws IOException {
        Properties result;// chargement une unique fois de la resource

        try (InputStream in = openInternalStream(url)) {
            result = new Properties();
            result.load(in);
        }
        return result;
    }

    public void copyResource(String resource, File file, String message) throws IOException {

        try (FileOutputStream out = new FileOutputStream(file)) {
            // on fait une copie brute en ne passant pas par un Properties
            // qui perd le formatage et les commentaires

            // chargement des ressources

            // sauvegarde dans le fichier cible
            try (InputStreamReader in = new InputStreamReader(new BufferedInputStream(openInternalStream(getRegistredResource(resource).getUrl())), StandardCharsets.UTF_8)) {
                IOUtils.copy(in, out, StandardCharsets.UTF_8);
            }

            log.debug(message);
        }
    }

    private Resource getRegistredResource(String resource) {
        return Objects.requireNonNull(resourceDefinitions.get(resource));
    }

    public void copyResource(URL resource, File file, String message) throws IOException {

        try (FileOutputStream out = new FileOutputStream(file)) {

            try (InputStream in = openInternalStream(resource)) {

                // sauvegarde dans le fichier cible
                IOUtils.copy(in, out);
            }

            log.debug(message);
        }
    }

    /**
     * Créer le répertoire si nécessaire à partir le l'option donnée.
     *
     * @param config la configuration utilisée
     * @param option l'option qui représentent le répertoire.
     * @return le fichier
     * @throws IOException pour tout problème de création de répertoire
     */
    public File createDirectory(ApplicationConfiguration config, ConfigOptionDef option) throws IOException {
        File dir = config.get().getOptionAsFile(option.getKey());
        createDirectory(dir);
        return dir;
    }

    /**
     * Créer tous les répertoires parents nécessaires à partir des options sur
     * répertoire ou fichier.
     *
     * @param config  la configuration utilisée
     * @param options les options qui représentent des répertoires ou fichiers.
     * @throws IOException pour tout problème de création de répertoire
     */
    public void createParentDirectory(ApplicationConfiguration config, ConfigOptionDef... options) throws IOException {
        for (ConfigOptionDef option : options) {
            File dir = config.get().getOptionAsFile(option.getKey()).getParentFile();
            createDirectory(dir);
        }
    }

    /**
     * Créer un répertoire s'il n'existe pas.
     *
     * @param dir le répertoire à créer
     * @return le fichier
     * @throws IOException pour tout problème de création de répertoire
     */
    protected File createDirectory(File dir) throws IOException {

        if (!dir.exists()) {
            log.debug(String.format("Create directory %s", dir));
            log.debug(String.format("Directory %s exists.", dir));
            boolean b = dir.mkdirs();
            if (!b) {
                throw new IOException(String.format("Can not create directory: %s", dir));
            }
        }
        return dir;
    }

    public void unzipToDirectory(String resourceName, ApplicationConfiguration config, ConfigOptionDef option) throws IOException {

        File dir = config.get().getOptionAsFile(option.getKey());
        createDirectory(dir);
        URL resourceUrl = getResourceUrl(resourceName);
        try (InputStream inputStream = openInternalStream(resourceUrl)) {
            Zips.uncompress(inputStream, dir);
        }
    }

    public URL getResourceUrl(String resource) {
        return getRegistredResource(resource).getUrl();
    }

    public String getResourceFilename(String resource) {
        return getRegistredResource(resource).getFilename();
    }

    public interface Resource {

        URL getUrl();

        boolean exists(File directory);

        File getFile(File directory);

        String getFilename();

        String getLocation();
    }

    public static class ClassPathResource implements Resource {

        private final String location;
        private URL url;

        public ClassPathResource(String location) {
            this.location = location;
        }

        @Override
        public String getLocation() {
            return location;
        }

        @Override
        public URL getUrl() {
            if (url == null) {
                url = ApplicationResourceManager.getResource(location);
            }
            return url;
        }

        @Override
        public boolean exists(File directory) {
            File file = getFile(directory);
            return file.exists();
        }

        @Override
        public File getFile(File directory) {
            return new File(directory, getFilename());
        }

        @Override
        public String getFilename() {
            return location.substring(1);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy