ResourceManager.java
- /*
- * @copyright defined in LICENSE.txt
- */
- package ship.build;
- import static hera.util.FilepathUtils.getCanonicalForm;
- import static hera.util.ObjectUtils.equal;
- import static hera.util.ObjectUtils.nvl;
- import static java.util.Arrays.asList;
- import static java.util.Collections.EMPTY_LIST;
- import static java.util.Collections.unmodifiableSet;
- import static org.slf4j.LoggerFactory.getLogger;
- import hera.server.ServerEvent;
- import hera.server.ServerListener;
- import hera.util.FilepathUtils;
- import java.io.File;
- import java.nio.file.Path;
- import java.nio.file.Paths;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Map;
- import java.util.Objects;
- import java.util.Optional;
- import java.util.Set;
- import lombok.Getter;
- import lombok.RequiredArgsConstructor;
- import lombok.Setter;
- import org.slf4j.Logger;
- import ship.ProjectFile;
- import ship.build.res.BuildResource;
- import ship.build.res.PackageResource;
- import ship.build.res.Project;
- import ship.build.res.Source;
- import ship.build.res.TestResource;
- import ship.util.FileWatcher;
- @RequiredArgsConstructor
- public class ResourceManager implements ServerListener {
- protected static final Set<Integer> eventFilter =
- unmodifiableSet(new HashSet(asList(FileWatcher.ANY_CHANGED)));
- protected final transient Logger logger = getLogger(getClass());
- protected final Map<String, Resource> cache = new HashMap<>();
- @Getter
- protected final Project project;
- @Getter
- @Setter
- protected PackageManager packageManager = new PackageManager();
- protected final Set<ResourceChangeListener> resourceChangeListeners = new HashSet<>();
- public void addResourceChangeListener(final ResourceChangeListener listener) {
- resourceChangeListeners.add(listener);
- }
- public void removeResourceChangeListener(final ResourceChangeListener listener) {
- resourceChangeListeners.remove(listener);
- }
- protected void fireEvent(final ResourceChangeEvent event) {
- for (final ResourceChangeListener listener : resourceChangeListeners) {
- listener.handle(event);
- }
- }
- /**
- * Return resource for {@code base}.
- *
- * @param path resource base
- *
- * @return resource for base
- */
- public synchronized Resource getResource(final String path) {
- logger.trace("Path: {}", path);
- final ProjectFile projectFile = project.getProjectFile();
- final String canonicalPath = getCanonicalForm(path);
- logger.trace("Canonical base: {}", canonicalPath);
- final Resource cached = cache.get(canonicalPath);
- if (null != cached) {
- return cached;
- }
- final Resource created = create(canonicalPath);
- cache.put(canonicalPath, created);
- logger.debug("{} added", canonicalPath);
- return created;
- }
- protected boolean isTarget(final String canonicalPath) {
- final ProjectFile projectFile = project.getProjectFile();
- return equal(canonicalPath, getCanonicalForm(projectFile.getTarget()));
- }
- protected boolean isTest(final String canonicalPath) {
- final ProjectFile projectFile = project.getProjectFile();
- return nvl(projectFile.getTests(), Collections.<String>emptyList())
- .stream().map(FilepathUtils::getCanonicalForm).anyMatch(canonicalPath::equals);
- }
- protected Resource create(final String canonicalPath) {
- if (isTarget(canonicalPath)) {
- return new BuildResource(project, canonicalPath);
- } else if (isTest(canonicalPath)) {
- return new TestResource(project, canonicalPath);
- } else if (canonicalPath.endsWith(".lua")) {
- return new Source(project, canonicalPath);
- } else {
- return new Resource(project, canonicalPath);
- }
- }
- public Resource getPackage(final String packageName) {
- final ResourceManager newResourceManager = packageManager.find(packageName);
- return new PackageResource(newResourceManager);
- }
- @Override
- public void handle(final ServerEvent event) {
- if (!eventFilter.contains(event.getType())) {
- logger.trace("Unhandled event: {}", event);
- return;
- }
- final Collection<File> files = nvl((Collection<File>) event.getNewData(), EMPTY_LIST);
- final Optional<Resource> cachedResourceOpt = files.stream().map(file -> {
- final String path = getCanonicalForm(file.getAbsolutePath());
- final String projectPath =
- getCanonicalForm(project.getPath().toAbsolutePath().toString());
- final Path relativePath =
- Paths.get(projectPath).relativize(Paths.get(path));
- logger.trace("Project path: {}, Path: {}, Relative path: {}",
- projectPath, path, relativePath);
- final String relativePathStr = relativePath.toString();
- logger.debug("Relative path: {}", relativePath);
- final String canonicalPath = getCanonicalForm(relativePathStr);
- logger.trace("Project relative path: {}", canonicalPath);
- return cache.get(canonicalPath);
- }).filter(Objects::nonNull).findFirst();
- if (cachedResourceOpt.isPresent()) {
- final Resource cached = cachedResourceOpt.get();
- logger.info("{} changed: {}", cached, event.getType());
- fireEvent(new ResourceChangeEvent(cached));
- }
- }
- }