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

net.dynamic_tools.service.JSResourceDependencyManagerImpl Maven / Gradle / Ivy

package net.dynamic_tools.service;

import net.dynamic_tools.exception.CircularDependencyException;
import net.dynamic_tools.model.JSResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: Peter
 * Date: 4/11/11
 * Time: 4:16 PM
 * To change this template use File | Settings | File Templates.
 */
@Component
public class JSResourceDependencyManagerImpl implements ResourceDependencyManager {
    private static final Logger logger = LoggerFactory.getLogger(JSResourceDependencyManagerImpl.class);

    private final List paths = new ArrayList();
    private final List mockPaths = new ArrayList();
    private final Map jsResourceMap = new HashMap();
    private final Map jsMockResourceMap = new HashMap();

    private FileFinder fileFinder;
    private JSDependencyReader jsDependencyReader;

    private static final String JS_EXTENSION = ".js";

    @Override
    public void addPaths(File... paths) {
        this.paths.addAll(Arrays.asList(paths));
    }

    @Override
    public void removePaths(File... paths) {
        this.paths.removeAll(Arrays.asList(paths));
    }

    @Override
    public void addMockPaths(File... paths) {
        this.mockPaths.addAll(Arrays.asList(paths));
    }

    @Override
    public void removeMockPaths(File... paths) {
        this.mockPaths.removeAll(Arrays.asList(paths));
    }

      public List getResourceByName(boolean useMocks, String... names) throws IOException, CircularDependencyException {
        Map jsResourceMap = new HashMap();
        List jsResources = new ArrayList();
        for (String name : names) {
            String fileName = name.replace('.', File.separatorChar) + JS_EXTENSION;
            File jsResourceFile = fileFinder.getFile(fileName, paths);

            JSResource jsResource = new JSResource(jsResourceFile, name);
            jsResourceMap.put(name, jsResource);
            jsResources.add(jsResource);
        }
        for (JSResource jsResource : jsResources) {
            Set dependencies = jsDependencyReader.readDependencies(jsResource.getJsResourceFile());
            for (String dependencyName : dependencies) {
                if (useMocks) {
                    List mockFirstPaths = new ArrayList(paths);
                    mockFirstPaths.addAll(0, mockPaths);

                    jsResource.addDependency(getResourceByName(dependencyName, jsResourceMap, mockFirstPaths));
                }
                else {
                    jsResource.addDependency(this.getResourceByName(dependencyName, jsResourceMap, paths));
                }
            }
        }
        return jsResources;
    }

    public JSResource getResourceByName(String name, Map jsResourceMap, List paths) throws IOException, CircularDependencyException {
        JSResource jsResource = jsResourceMap.get(name);

        if (jsResource == null) {
                String fileName = name.replace('.', File.separatorChar) + JS_EXTENSION;

                File jsResourceFile = fileFinder.getFile(fileName, paths);

                jsResource = new JSResource(jsResourceFile, name);

                jsResourceMap.put(name, jsResource);

                Set dependencies = jsDependencyReader.readDependencies(jsResourceFile);
                for (String dependencyName : dependencies) {
                    jsResource.addDependency(getResourceByName(dependencyName, jsResourceMap, paths));
                }
        }
        return jsResource;
    }

    @Override
    public List getResourcesFor(String... names) throws IOException, CircularDependencyException {
        return getResourcesFor(getResourceByName(false, names));
    }

    @Override
    public List getResourcesFor(JSResource... namedResources) {
        return getResourcesFor(Arrays.asList(namedResources));
    }

    public List getResourcesFor(List jsResources) {
        Map> dependencyMap = new HashMap>();
        addResourcesToDependencyMap(jsResources, dependencyMap);

        List orderedResources = new ArrayList();
        while (dependencyMap.size() > 0) {
            List jsResourcesWithSatisfiedDependencies = new ArrayList();
            Set jsResourcesKeys = new HashSet(dependencyMap.keySet());
            for (JSResource jsResource : jsResourcesKeys) {
                Set remainingDependencies = dependencyMap.get(jsResource);
                if (remainingDependencies.size() == 0) {
                    jsResourcesWithSatisfiedDependencies.add(jsResource);
                    dependencyMap.remove(jsResource);
                }
            }

            if (jsResourcesWithSatisfiedDependencies.size() == 0) {
                throw new RuntimeException("Unable to order resources due to unsatisfied dependencies");
            }

            Collections.sort(jsResourcesWithSatisfiedDependencies, new Comparator() {
                @Override
                public int compare(JSResource o1, JSResource o2) {
                    return o1.getName().compareTo(o2.getName());
                }
            });

            orderedResources.addAll(jsResourcesWithSatisfiedDependencies);

            for (Set jsResourceDependencies : dependencyMap.values()) {
                jsResourceDependencies.removeAll(orderedResources);
            }
        }

        return orderedResources;
    }

    private void addResourcesToDependencyMap(Collection jsResources, Map> dependencyMap) {
        for (JSResource jsResource : jsResources) {
            if (!dependencyMap.containsKey(jsResource)) {
                Set dependencies = jsResource.getDependencies();
                dependencyMap.put(jsResource, new HashSet(dependencies));
                addResourcesToDependencyMap(dependencies, dependencyMap);
            }
        }
    }

    @Override
    public List getTestResourcesFor(String... names) throws IOException, CircularDependencyException {
        List jsResources = getResourceByName(true, names);
        return getResourcesFor(jsResources);
    }

    private void addJSResourceAndDependenciesToMap(Map jsResourceMap, JSResource jsResource) {
        if (!jsResourceMap.containsKey(jsResource.getName())) {
            jsResourceMap.put(jsResource.getName(), jsResource);
            for (JSResource jsResourceDependency : jsResource.getDependencies()) {
                addJSResourceAndDependenciesToMap(jsResourceMap, jsResourceDependency);
            }
        }
    }

    @Override
    public boolean contains(String name) throws IOException, CircularDependencyException {
        return getResourceByName(false, name) != null;
    }

    @Override
    public List getAllResources() throws IOException, CircularDependencyException {
        Map jsResourceMap = new HashMap();
        Map> dependencyMap = new HashMap>();
        for (File path : paths) {
            List jsFiles = fileFinder.getAllFilesWithExtension(path, JS_EXTENSION);
            for (File jsFile : jsFiles) {
                JSResource jsResource = new JSResource(jsFile, getNameFromLocation(path, jsFile));
                String resourceName = jsResource.getName();
                if (jsResourceMap.containsKey(resourceName)) {
                    logger.warn("Original resource {} will be overwritten by {}", jsResourceMap.get(resourceName).getJsResourceFile(), jsFile);
                    dependencyMap.remove(resourceName);
                }

                jsResourceMap.put(resourceName, jsResource);
                dependencyMap.put(resourceName, jsDependencyReader.readDependencies(jsFile));
            }
        }

        for (String jsResourceName : dependencyMap.keySet()) {
            JSResource jsResource = jsResourceMap.get(jsResourceName);
            for (String dependencyName : dependencyMap.get(jsResourceName)) {
                JSResource dependency = jsResourceMap.get(dependencyName);
                if (dependency == null) {
                    throw new RuntimeException("Cannot resolve the dependency of " + jsResourceName + " on " + dependencyName);
                }
                jsResource.addDependency(dependency);
            }
        }

        return getResourcesFor(new ArrayList(jsResourceMap.values()));
    }

    public String getNameFromLocation(File rootPath, File jsFile) {
		String jsFileName = jsFile.getName();
		String name = jsFileName.substring(0, jsFileName.length() - 3);
		File parent = jsFile.getParentFile();
		while (!parent.equals(rootPath)) {
			name = parent.getName() + "." + name;
			parent = parent.getParentFile();
		}
		return name;
	}

    public void setFileFinder(FileFinder fileFinder) {
        this.fileFinder = fileFinder;
    }

    public void setJsDependencyReader(JSDependencyReader jsDependencyReader) {
        this.jsDependencyReader = jsDependencyReader;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy