Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,4 @@ gradle-app.setting

# End of https://www.toptal.com/developers/gitignore/api/netbeans,intellij,java,gradle,eclipse
application/db/
config.json
3 changes: 3 additions & 0 deletions application/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ dependencies {
implementation 'org.apache.logging.log4j:log4j-api:2.14.1'
implementation 'org.apache.logging.log4j:log4j-core:2.14.1'
implementation 'org.apache.logging.log4j:log4j-slf4j18-impl:2.14.1'

implementation 'org.jooq:jooq:3.15.3'

implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.5'

testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.0'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,48 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.togetherjava.tjbot.commands.CommandHandler;
import org.togetherjava.tjbot.config.Config;
import org.togetherjava.tjbot.db.Database;

import javax.security.auth.login.LoginException;
import java.io.IOException;
import java.nio.file.Path;
import java.sql.SQLException;

/***
/**
* Main class of the application. Use {@link #main(String[])} to start an instance of it.
*/
public enum Application {
;

private static final Logger logger = LoggerFactory.getLogger(Application.class);
private static final String DEFAULT_CONFIG_PATH = "config.json";

/**
* Starts the application.
*
* @param args command line arguments - [the token of the bot, the path to the database]
* @param args command line arguments - [the path to the configuration file (optional, by
* default "config.json")]
*/
public static void main(final String[] args) {
if (args.length != 2) {
throw new IllegalArgumentException("Expected two arguments but " + args.length
+ " arguments were provided. The first argument must be the token of the bot"
+ " and the second the path to the database.");
if (args.length > 1) {
throw new IllegalArgumentException("Expected no or one argument but " + args.length
+ " arguments were provided. The first argument is the path to the configuration file. If no argument was provided, '"
+ DEFAULT_CONFIG_PATH + "' will be assumed.");
}
String token = args[0];
String databasePath = args[1];

Path configPath = Path.of(args.length == 1 ? args[0] : DEFAULT_CONFIG_PATH);
try {
runBot(token, Path.of(databasePath));
Config.load(configPath);
} catch (IOException e) {
logger.error("Unable to load the configuration file from path '{}'",
configPath.toAbsolutePath(), e);
return;
}

try {
Config config = Config.getInstance();
runBot(config.getToken(), Path.of(config.getDatabasePath()));
} catch (Exception t) {
logger.error("Unknown error", t);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package org.togetherjava.tjbot.config;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.nio.file.Path;
import java.util.Objects;

/**
* Configuration of the application, as singleton.
* <p>
* Create instances using {@link #load(Path)} and then access them with {@link #getInstance()}.
*/
public final class Config {

private static Config config;

private final String token;
private final String databasePath;
private final String projectWebsite;
private final String discordGuildInvite;

@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
private Config(@JsonProperty("token") String token,
@JsonProperty("databasePath") String databasePath,
@JsonProperty("projectWebsite") String projectWebsite,
@JsonProperty("discordGuildInvite") String discordGuildInvite) {
this.token = token;
this.databasePath = databasePath;
this.projectWebsite = projectWebsite;
this.discordGuildInvite = discordGuildInvite;
}

/**
* Loads the configuration from the given file. Will override any previously loaded data.
* <p>
* Access the instance using {@link #getInstance()}.
*
* @param path the configuration file, as JSON object
* @throws IOException if the file could not be loaded
*/
public static void load(Path path) throws IOException {
config = new ObjectMapper().readValue(path.toFile(), Config.class);
}

/**
* Gets the singleton instance of the configuration.
* <p>
* Must be loaded beforehand using {@link #load(Path)}.
*
* @return the previously loaded configuration
*/
public static Config getInstance() {
return Objects.requireNonNull(config,
"can not get the configuration before it has been loaded");
}

/**
* Gets the token of the Discord bot to connect this application to.
*
* @return the Discord bot token
*/
public String getToken() {
return token;
}

/**
* Gets the path where the database of the application is located at.
*
* @return the path of the database
*/
public String getDatabasePath() {
return databasePath;
}

/**
* Gets a URL of the project's website, for example to tell the user where he can contribute.
*
* @return the website of the project
*/
public String getProjectWebsite() {
return projectWebsite;
}

/**
* Gets an invite-URL to join the Discord guild this application is connected to.
*
* @return an invite-URL for this Discord guild
*/
public String getDiscordGuildInvite() {
return discordGuildInvite;
}
}