com.buschmais.jqassistant.plugin.common.api.scanner.ContainerFileResolver Maven / Gradle / Ivy
The newest version!
package com.buschmais.jqassistant.plugin.common.api.scanner;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import com.buschmais.jqassistant.core.scanner.api.ScannerContext;
import com.buschmais.jqassistant.plugin.common.api.model.FileContainerDescriptor;
import com.buschmais.jqassistant.plugin.common.api.model.FileDescriptor;
/**
* A file resolver strategy for file containers.
*/
public class ContainerFileResolver extends AbstractFileResolver {
private Map requiredFiles = new HashMap<>();
private Map containedFiles = new HashMap<>();
private FileContainerDescriptor fileContainerDescriptor;
public ContainerFileResolver(FileContainerDescriptor fileContainerDescriptor) {
this.fileContainerDescriptor = fileContainerDescriptor;
this.containedFiles = getCache(fileContainerDescriptor.getContains());
this.requiredFiles = getCache(fileContainerDescriptor.getRequires());
}
@Override
public D require(String requiredPath, String containedPath, Class type, ScannerContext context) {
FileDescriptor fileDescriptor = containedFiles.get(containedPath);
D result;
if (fileDescriptor != null) {
result = toFileDescriptor(fileDescriptor, type, requiredPath, context);
containedFiles.put(containedPath, result);
} else {
fileDescriptor = requiredFiles.get(containedPath);
result = toFileDescriptor(fileDescriptor, type, requiredPath, context);
requiredFiles.put(containedPath, result);
}
return result;
}
@Override
public D match(String containedPath, Class type, ScannerContext context) {
FileDescriptor fileDescriptor = requiredFiles.remove(containedPath);
return toFileDescriptor(fileDescriptor, type, containedPath, context);
}
/**
* Flush the caches to the store.
*/
public void flush() {
createHierarchy();
sync(fileContainerDescriptor.getRequires(), requiredFiles);
sync(fileContainerDescriptor.getContains(), containedFiles);
}
/**
* Sync the given target collection with the new state from the cache map.
*
* @param target
* The target collection.
* @param after
* The new state to sync to.
*/
private void sync(Collection target, Map after) {
Map before = getCache(target);
Map all = new HashMap<>();
all.putAll(before);
all.putAll(after);
for (Map.Entry entry : all.entrySet()) {
String key = entry.getKey();
FileDescriptor fileDescriptor = entry.getValue();
boolean hasBefore = before.containsKey(key);
boolean hasAfter = after.containsKey(key);
if (hasBefore && !hasAfter) {
target.remove(fileDescriptor);
} else if (!hasBefore && hasAfter) {
target.add(fileDescriptor);
}
}
}
/**
* Creates cache map from the given collection of file descriptors.
*
* @param fileDescriptors
* The collection of file descriptors.
* @return The cache map.
*/
private Map getCache(Iterable fileDescriptors) {
Map cache = new HashMap<>();
for (FileDescriptor fileDescriptor : fileDescriptors) {
cache.put(fileDescriptor.getFileName(), fileDescriptor);
}
return cache;
}
/**
* Build the hierarchy of the container entries, i.e. add contains relations
* from containers to their children.
*/
private void createHierarchy() {
for (Map.Entry entry : containedFiles.entrySet()) {
String relativePath = entry.getKey();
FileDescriptor fileDescriptor = entry.getValue();
int separatorIndex = relativePath.lastIndexOf('/');
if (separatorIndex != -1) {
String parentName = relativePath.substring(0, separatorIndex);
FileDescriptor parentDescriptor = containedFiles.get(parentName);
if (parentDescriptor instanceof FileContainerDescriptor) {
((FileContainerDescriptor) parentDescriptor).getContains().add(fileDescriptor);
}
}
}
}
/**
* Adds a file to the container.
*
* @param path
* The path of the file.
* @param fileDescriptor
* The file descriptor.
*/
public void put(String path, FileDescriptor fileDescriptor) {
containedFiles.put(path, fileDescriptor);
}
/**
* Returns the size of the container.
*
* @return The size of the container.
*/
public int size() {
return containedFiles.size();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy