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

inti.ws.spring.resource.config.ResourceConfigProviderImpl Maven / Gradle / Ivy

Go to download

An utility library for spring-based web-services for compressing / optimizing JS and CSS resources.

The newest version!
/**
 * Copyright 2012 the project-owners
 *
 *    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 inti.ws.spring.resource.config;

import inti.ws.spring.resource.WebResource;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.inject.Inject;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpHeaders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Component;
import org.springframework.web.context.support.ServletContextResource;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

@Component
public class ResourceConfigProviderImpl implements InitializingBean, ResourceConfigProvider {

    private static final String DEFAULT_CONFIG_NAME = "_default";
    private static final String CONFIG_EXTENSION = ".json";
    private static final String HOSTS_DIR = "/WEB-INF/hosts/";
    private static final String HOSTS_META_DIR = "META-INF/hosts/index";
    private static final Logger LOGGER = LoggerFactory.getLogger(ResourceConfigProviderImpl.class);

    @Inject
    protected ServletContext ctx;
    @Inject
    protected ConfigParserProvider configParserProvider;
    protected boolean updateConfig = false;
    protected Map lastModifies = new HashMap();
    protected Map> hostToConfigfileMapping = new HashMap<>();
    protected Map> configs = new HashMap<>();
    protected ObjectMapper mapper = new ObjectMapper();

    @Override
    public void afterPropertiesSet() throws Exception {
        updateConfig = true;
        Set paths = ctx.getResourcePaths(HOSTS_DIR);
        Enumeration urls = Thread.currentThread().getContextClassLoader().getResources(HOSTS_META_DIR);
        Set metaPaths = getPaths(urls);
        String host;

        metaPaths.addAll(paths);
        LOGGER.debug("afterPropertiesSet - available paths={}", metaPaths);

        for (String path : metaPaths) {
            if (path.endsWith(CONFIG_EXTENSION)) {
                LOGGER.debug("afterPropertiesSet - scanning config-file={}", path);

                host = path.substring(path.lastIndexOf('/') + 1, path.lastIndexOf(CONFIG_EXTENSION));

                List resources = hostToConfigfileMapping.get(host);

                if (resources == null) {
                    resources = new ArrayList<>();
                    hostToConfigfileMapping.put(host, resources);
                }

                resources.add(path);

                update(host);
            }
        }
        updateConfig = !(System.getProperty("DEBUG_MODE") == null || !System.getProperty("DEBUG_MODE").equals("true"));
    }

    protected Set getPaths(Enumeration urls) {
        URL url;
        InputStream input;
        List lines;
        Set paths = new HashSet<>();
        String tmp;

        if (urls != null) {

            while (urls.hasMoreElements()) {

                try {
                    url = urls.nextElement();
                    LOGGER.debug("getPaths - checking url: {}", url);
                    input = url.openStream();

                    try {
                        lines = IOUtils.readLines(input);

                        for (String line : lines) {
                            if (line.trim().length() > 0) {
                                tmp = url.toExternalForm();
                                paths.add(tmp.substring(0, tmp.length() - 5) + line);
                            }
                        }
                        LOGGER.debug("getPaths - got paths {} from url {}", paths, url);

                    } finally {
                        try {
                            input.close();
                        } catch (IOException exception) {
                            LOGGER.error("error while reading hosts config", exception);
                        }
                    }

                } catch (IOException exception) {
                    LOGGER.error("error while reading hosts config", exception);
                }

            }

        }

        return paths;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public ResourceConfig getResourceConfig(HttpServletRequest request, String pluginName) {
        List configs = getResourceConfigs(request);
        List candidates = new ArrayList<>();

        // search all candicates
        for (ResourceConfig config : configs) {

            if (config.getName().equals(pluginName)) {

                candidates.add(config);

            }

        }

        if (!candidates.isEmpty()) {

            ResourceConfig config = new ResourceConfig();
            Map resources = new HashMap<>();

            // put all resources in a new ResourceConfig object
            for (ResourceConfig resourceConfig : candidates) {
                resources.putAll((Map) resourceConfig.getResources());
            }

            config.setResources(resources);

            return config;

        }

        return null;
    }

    @Override
    public List getResourceConfigs(HttpServletRequest request) {
        String key = getKey(request);

        if (updateConfig) {
            try {
                update(key);
            } catch (Exception exception) {
                LOGGER.error("", exception);
            }
        }

        return configs.get(key);
    }

    protected String getKey(HttpServletRequest request) {
        String key = request.getHeader(HttpHeaders.HOST);
        int index;

        if (key == null) {
            key = DEFAULT_CONFIG_NAME;
        } else if ((index = key.indexOf(":")) != -1) {
            key = key.substring(0, index);
        }

        if (!configs.containsKey(key)) {
            key = DEFAULT_CONFIG_NAME;
        }

        return key;
    }

    protected void update(String key) throws Exception {
        Resource configFile;
        JsonNode configNode;
        InputStream inputStream;

        LOGGER.debug("update - paths for key {}: {}", key, hostToConfigfileMapping.get(key));

        for (String path : hostToConfigfileMapping.get(key)) {

            if (path.startsWith("/")) {
                configFile = new ServletContextResource(ctx, path);
            } else {
                configFile = new UrlResource(path);
            }

            LOGGER.debug("update - updating {} for key {}", path, key);
            if (lastModifies.containsKey(path) && configFile.lastModified() <= lastModifies.get(path)) {
                LOGGER.debug("update - no newer version available for {} for key {}", path, key);
                continue;
            } else {
                lastModifies.put(path, configFile.lastModified());
            }

            inputStream = configFile.getInputStream();
            try {
                configNode = mapper.readTree(inputStream);
            } finally {
                inputStream.close();
            }

            if (configNode != null) {

                configure(key, configNode);

            }

        }

    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    protected void configure(String host, JsonNode configNode) throws Exception {
        Map> parsers;
        ConfigParser parser;
        Entry field;
        Iterator> fields;
        Map resources;
        List resourceConfigs;
        Map> resourceStack = new HashMap<>();
        ResourceConfig config;

        fields = configNode.fields();
        parsers = configParserProvider.getConfigParsers(Thread.currentThread().getContextClassLoader());

        LOGGER.debug("update - scanning with parsers={}", parsers);

        resourceConfigs = configs.get(host);
        if (resourceConfigs == null) {
            resourceConfigs = new ArrayList<>();
            configs.put(host, resourceConfigs);
        }

        while (fields.hasNext()) {

            field = fields.next();
            parser = parsers.get(field.getKey());
            LOGGER.debug("update - got parser for field={}: {}", field.getKey(), parser);
            config = new ResourceConfig();

            if (parser != null) {
                resources = parser.instanceWebResources(mapper, field.getValue());
                resourceStack.put(field.getKey(), resources);

                if (parser.getConfigParserSettings() != null) {

                    config.setName(field.getKey());
                    config.setResources(resources);
                    config.setSettings(parser.getConfigParserSettings());
                    resourceConfigs.add(config);

                }

            }

        }

        fields = configNode.fields();
        while (fields.hasNext()) {
            field = fields.next();
            parser = parsers.get(field.getKey());
            if (parser != null) {
                parser.configureWebResources(mapper, field.getValue(), (Map) resourceStack.get(field.getKey()),
                                (Map) resourceStack);
            }
        }

        LOGGER.debug("update - added config with host={}: {}", host, resourceConfigs);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy