package org.drooms.launcher.tournament; import org.apache.commons.lang3.tuple.ImmutablePair; import org.drooms.api.Game; import org.drooms.api.Player; import org.drooms.impl.util.PlayerProperties; import org.drooms.util.CommonProperties; import java.io.File; import java.util.*; import java.util.stream.Collectors; // FIXME document player config file format. /** * Prepares the tournament properties by reading them from a property file. * * <p> * Mandatory properties are: * </p> * * <dl> * <dt>game.class</dt> * <dd>Which {@link Game} implementation the {@link DroomsTournament} should use. Fully qualified name.</dd> * <dt>players</dt> * <dd>Path to the file containing descriptions of the {@link Player}s that will participate in the tournament. See * {@link PlayerProperties}. Relative to the current working directory.</dd> * <dt>playgrounds</dt> * <dd>Comma-separated list of playground on which to play the tournament.</dd> * </dl> * * <p> * Optional properties are: * </p> * * <dl> * <dt>runs</dt> * <dd>How many times should each playground be played. Number greater than 0, default value is 1.</dd> * <dt>folder.resources</dt> * <dd>Where to load all input files from, relative to the current working directory. If it doesn't exist, it is * created. Default value is "src/main/resources".</dd> * <dt>folder.target</dt> * <dd>Where to write all output data, relative to the current working directory. If it doesn't exist, it is created. * Default value is "target/drooms".</dd> * </dl> * */ public class TournamentProperties extends CommonProperties { @SuppressWarnings("unchecked") private static Class<? extends Game> getGameImpl(final String id) { try { return (Class<? extends Game>) Class.forName(id); } catch (final ClassNotFoundException e) { throw new IllegalArgumentException("Cannot instantiate game class.", e); } } public static TournamentProperties read(final File f) { return new TournamentProperties(CommonProperties.loadPropertiesFromFile(f)); } private final Class<? extends Game> gameClass; private final File resourceFolder; private final File targetFolder; private final Collection<ImmutablePair<File, File>> playgrounds; private final int numberOfRunsPerPlayground; private final Collection<Player> players; private TournamentProperties(final Properties p) { super(p); this.gameClass = TournamentProperties.getGameImpl(this.getMandatoryProperty("game.class")); this.numberOfRunsPerPlayground = Integer.valueOf(this.getOptionalProperty("runs", "1")); // prepare folders this.resourceFolder = new File(this.getOptionalProperty("folder.resources", "src/main/resources")); if (!this.resourceFolder.exists()) { this.resourceFolder.mkdirs(); } this.targetFolder = new File(this.getOptionalProperty("folder.target", "target/drooms")); if (!this.targetFolder.exists()) { this.targetFolder.mkdirs(); } // prepare a list of players final File playerConfigFile = new File(this.resourceFolder, this.getMandatoryProperty("players")); this.players = Collections.unmodifiableList(new PlayerProperties(playerConfigFile).read()); // parse the playgrounds this.playgrounds = Collections.unmodifiableCollection(Arrays.stream(this.getMandatoryProperty("playgrounds") .split("\\Q,\\E")).map(playgroundName -> { final File playground = new File(this.resourceFolder, playgroundName + ".playground"); final File config = new File(this.resourceFolder, playgroundName + ".cfg"); return new ImmutablePair<>(playground, config); }).collect(Collectors.toList())); } public Class<? extends Game> getGameClass() { return this.gameClass; } public int getNumberOfRunsPerPlayground() { return this.numberOfRunsPerPlayground; } public Collection<Player> getPlayers() { return this.players; } public Collection<ImmutablePair<File, File>> getPlaygrounds() { return this.playgrounds; } public File getResourceFolder() { return this.resourceFolder; } public File getTargetFolder() { return this.targetFolder; } }