Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 {
var 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;
}
}