package org.flywaydb.core.internal.scanner;
import org.flywaydb.core.api.Location;
import org.flywaydb.core.api.logging.Log;
import org.flywaydb.core.api.logging.LogFactory;
import org.flywaydb.core.internal.clazz.ClassProvider;
import org.flywaydb.core.internal.resource.LoadableResource;
import org.flywaydb.core.internal.resource.ResourceProvider;
import org.flywaydb.core.internal.scanner.android.AndroidScanner;
import org.flywaydb.core.internal.scanner.classpath.ClassPathLocationScanner;
import org.flywaydb.core.internal.scanner.classpath.ClassPathScanner;
import org.flywaydb.core.internal.scanner.classpath.ResourceAndClassScanner;
import org.flywaydb.core.internal.scanner.filesystem.FileSystemScanner;
import org.flywaydb.core.internal.util.FeatureDetector;
import org.flywaydb.core.internal.util.StringUtils;
import java.nio.charset.Charset;
import java.util.*;
public class Scanner<I> implements ResourceProvider, ClassProvider<I> {
private static final Log LOG = LogFactory.getLog(Scanner.class);
private final List<LoadableResource> resources = new ArrayList<>();
private final List<Class<? extends I>> classes = new ArrayList<>();
public Scanner(Class<I> implementedInterface, Collection<Location> locations, ClassLoader classLoader, Charset encoding
, ResourceNameCache resourceNameCache
, LocationScannerCache locationScannerCache
) {
FileSystemScanner fileSystemScanner = new FileSystemScanner(encoding
);
boolean android = new FeatureDetector(classLoader).isAndroidAvailable();
for (Location location : locations) {
if (location.isFileSystem()) {
resources.addAll(fileSystemScanner.scanForResources(location));
} else {
ResourceAndClassScanner<I> resourceAndClassScanner = android
? new AndroidScanner<>(implementedInterface, classLoader, encoding, location)
: new ClassPathScanner<>(implementedInterface, classLoader, encoding, location, resourceNameCache, locationScannerCache);
resources.addAll(resourceAndClassScanner.scanForResources());
classes.addAll(resourceAndClassScanner.scanForClasses());
}
}
}
@Override
public LoadableResource getResource(String name) {
for (LoadableResource resource : resources) {
String fileName = resource.getRelativePath();
if (fileName.equals(name)) {
return resource;
}
}
return null;
}
public Collection<LoadableResource> getResources(String prefix, String... suffixes) {
List<LoadableResource> result = new ArrayList<>();
for (LoadableResource resource : resources) {
String fileName = resource.getFilename();
if (StringUtils.startsAndEndsWith(fileName, prefix, suffixes)) {
result.add(resource);
} else {
LOG.debug("Filtering out resource: " + resource.getAbsolutePath() + " (filename: " + fileName + ")");
}
}
return result;
}
public Collection<Class<? extends I>> getClasses() {
return Collections.unmodifiableCollection(classes);
}
}