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

org.polyfillservice.api.services.FinancialTimesPolyfillLoaderService Maven / Gradle / Ivy

The newest version!
package org.polyfillservice.api.services;

import org.polyfillservice.api.components.Polyfill;
import org.polyfillservice.api.components.ServiceConfig;
import org.polyfillservice.api.interfaces.PolyfillConfigLoaderService;
import org.polyfillservice.api.interfaces.PolyfillLoaderService;
import org.polyfillservice.api.interfaces.PolyfillLocation;
import org.polyfillservice.api.interfaces.ResourceLoaderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

/**
 * Created by smo on 2/25/17.
 * Service to load and construct Financial Times' polyfills from file system.
 * Financial Times' polyfill folder structure:
 * polyfillName
 * - meta.json
 * - min.js
 * - raw.js
 */
@Service("all")
class FinancialTimesPolyfillLoaderService implements PolyfillLoaderService, ResourceLoaderService {

    private static final String ALIASES_KEY = "aliases";
    private static final String BROWSER_REQUIREMENTS_KEY = "browsers";
    private static final String DETECT_SOURCE_KEY = "detectSource";
    private static final String DEPENDENCIES_KEY = "dependencies";
    private static final String LICENSE_KEY = "license";
    private static final String REPO_KEY = "repo";
    private static final String TEST_KEY = "test";
    private static final String TESTS_SOURCE_KEY = "testsSource";

    private static final String META_FILENAME = "meta.json";
    private static final String MIN_FILENAME = "min.js";
    private static final String RAW_FILENAME = "raw.js";

    @javax.annotation.Resource(name = "aliases")
    private Map> aliases;

    @Autowired
    private ServiceConfig serviceConfig;

    @Autowired
    private PolyfillConfigLoaderService configLoader;

    @Override
    public Map loadPolyfills(List polyfillLocations) {

        if (polyfillLocations == null || polyfillLocations.isEmpty()) {
            return Collections.emptyMap();
        }

        List activePolyfills = serviceConfig.getPolyfills();
        if (!activePolyfills.isEmpty()) {
            return loadPartialPolyfills(polyfillLocations, activePolyfills);
        }

        return loadAllPolyfills(polyfillLocations);
    }

    private Map loadPartialPolyfills(List polyfillLocations,
            List activePolyfills) {

        Map polyfills = new HashMap<>();

        Queue processQueue = new LinkedList<>(activePolyfills);
        while (!processQueue.isEmpty()) {
            String polyfillName = processQueue.remove();
            if (polyfills.containsKey(polyfillName)) {
                continue;
            }

            // resolve alias
            List polyfillGroup = this.aliases.get(polyfillName);
            if (polyfillGroup != null) {
                processQueue.addAll(polyfillGroup);
                continue;
            }

            Polyfill polyfill = loadPolyfill(polyfillLocations, polyfillName);
            if (polyfill != null) {
                polyfills.put(polyfillName, polyfill);
                processQueue.addAll(polyfill.getDependencies());
            }
        }

        return Collections.unmodifiableMap(polyfills);
    }

    private Map loadAllPolyfills(List polyfillLocations) {

        Map polyfills = new HashMap<>();

        for (PolyfillLocation location : polyfillLocations) {
            String polyfillsPath = location.getPath();
            try {
                getResources(polyfillsPath, "*", "meta.json").forEach(polyfillResource -> {
                    try {
                        String polyfillName = getBaseDirectoryName(polyfillResource);
                        if (!polyfills.containsKey(polyfillName)) {
                            Polyfill polyfill = loadPolyfill(polyfillsPath, polyfillName);
                            polyfills.put(polyfill.getName(), polyfill);
                        }
                    } catch (IOException e) {
                        System.err.println("[Warning] Unable to load polyfill from resource: "
                                + polyfillResource.toString());
                    }
                });
            } catch (IOException e) {
                System.err.println("[Warning] Unable to load polyfills from " + polyfillsPath);
            }
        }

        return Collections.unmodifiableMap(polyfills);
    }

    /*
     * Implementation-specific helpers
     */

    private Polyfill loadPolyfill(List polyfillLocationList, String polyfillName) {
        Polyfill polyfill = null;
        for (PolyfillLocation location : polyfillLocationList) {
            try {
                polyfill = loadPolyfill(location.getPath(), polyfillName);
                // found polyfill, no need to look at other locations
                break;
            } catch (IOException e) {
                // ignore. unable to find polyfill from current directory
            }
        }
        // just log if polyfill is not found in any polyfill location
        if (polyfill == null) {
            System.err.println("[Warning] Unable to load polyfill: " + polyfillName);
        }
        return polyfill;
    }

    private Polyfill loadPolyfill(String polyfillsPath, String polyfillName) throws IOException {
        String polyfillDir = Paths.get(polyfillsPath, polyfillName).toString();
        Map meta = configLoader.getConfig(polyfillDir, META_FILENAME);
        String rawSource = resourceToString(getResource(polyfillDir, RAW_FILENAME));
        String minSource = resourceToString(getResource(polyfillDir, MIN_FILENAME));

        return new Polyfill.Builder(polyfillName)
                .rawSource( rawSource )
                .minSource( minSource )
                .aliases( getList(meta, ALIASES_KEY) )
                .browserRequirements( getMap(meta, BROWSER_REQUIREMENTS_KEY) )
                .dependencies( getList(meta, DEPENDENCIES_KEY) )
                .license( getString(meta, LICENSE_KEY) )
                .repository( getString(meta, REPO_KEY) )
                .detectSource( getString(meta, DETECT_SOURCE_KEY) )
                .testsSource( getString(meta, TESTS_SOURCE_KEY) )
                .isTestable( getIsTestable(meta) )
                .build();
    }

    private boolean getIsTestable(Map meta) {
        Map testMap = getMap(meta, TEST_KEY);
        String testsSource = getString(meta, TESTS_SOURCE_KEY);
        return testsSource != null && !testsSource.isEmpty() && (Boolean)testMap.getOrDefault("ci", true);
    }

    /*
     * Generic helpers
     */

    private String getString(Map map, String key) {
        Object value = map.get(key);
        return (value instanceof String) ? (String)value : null;
    }

    private List getList(Map map, String key) {
        return (List)map.getOrDefault(key, Collections.emptyList());
    }

    private Map getMap(Map map, String key) {
        return (Map)map.getOrDefault(key, Collections.emptyMap());
    }

    private String getBaseDirectoryName(Resource resource) throws IOException {
        Path path = FileSystems.getDefault().getPath(resource.getURI().toString());
        return path.getParent().getFileName().toString();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy