001package io.ebean.migration.runner;
002
003import io.ebean.migration.MigrationConfig;
004import io.ebean.migration.MigrationVersion;
005import org.avaje.classpath.scanner.Resource;
006import org.avaje.classpath.scanner.ResourceFilter;
007import org.avaje.classpath.scanner.core.Scanner;
008import org.slf4j.Logger;
009import org.slf4j.LoggerFactory;
010
011import java.util.ArrayList;
012import java.util.Collections;
013import java.util.List;
014
015/**
016 * Loads the DB migration resources and sorts them into execution order.
017 */
018public class LocalMigrationResources {
019
020  private static final Logger logger = LoggerFactory.getLogger(LocalMigrationResources.class);
021
022  private final MigrationConfig migrationConfig;
023
024  private final List<LocalMigrationResource> versions = new ArrayList<>();
025
026  /**
027   * Construct with configuration options.
028   */
029  public LocalMigrationResources(MigrationConfig migrationConfig) {
030    this.migrationConfig = migrationConfig;
031  }
032
033  /**
034   * Read all the migration resources (SQL scripts) returning true if there are versions.
035   */
036  public boolean readResources() {
037
038    String migrationPath = migrationConfig.getMigrationPath();
039
040    ClassLoader classLoader = migrationConfig.getClassLoader();
041
042    Scanner scanner = new Scanner(classLoader);
043    List<Resource> resourceList = scanner.scanForResources(migrationPath, new Match(migrationConfig));
044
045    logger.debug("resources: {}", resourceList);
046
047    for (Resource resource : resourceList) {
048      String filename = resource.getFilename();
049      if (filename.endsWith(migrationConfig.getApplySuffix())) {
050        int pos = filename.lastIndexOf(migrationConfig.getApplySuffix());
051        String mainName = filename.substring(0, pos);
052
053        MigrationVersion migrationVersion = MigrationVersion.parse(mainName);
054        LocalMigrationResource res = new LocalMigrationResource(migrationVersion, resource.getLocation(), resource);
055        versions.add(res);
056      }
057    }
058
059    Collections.sort(versions);
060    return !versions.isEmpty();
061  }
062
063  /**
064   * Return the list of migration resources in version order.
065   */
066  public List<LocalMigrationResource> getVersions() {
067    return versions;
068  }
069
070
071  /**
072   * Filter used to find the migration scripts.
073   */
074  private static class Match implements ResourceFilter {
075
076    private final MigrationConfig migrationConfig;
077
078    Match(MigrationConfig migrationConfig) {
079      this.migrationConfig = migrationConfig;
080    }
081
082    @Override
083    public boolean isMatch(String name) {
084      return name.endsWith(migrationConfig.getApplySuffix());
085    }
086  }
087}