Apply suggestions from code review

Co-authored-by: CyB3RC0nN0R <kske@outlook.de>
This commit is contained in:
delvh 2020-08-23 13:39:31 +02:00
parent c784ebb787
commit ddbf9acd07
9 changed files with 73 additions and 107 deletions

View File

@ -32,9 +32,9 @@ public final class ClientConfig extends Config {
private ClientConfig() { private ClientConfig() {
super(".envoy"); super(".envoy");
put("server", "s", identity(), true); put("server", "s", identity());
put("port", "p", Integer::parseInt, true); put("port", "p", Integer::parseInt);
put("localDB", "db", File::new, true); put("localDB", "db", File::new);
put("ignoreLocalDB", "nodb", Boolean::parseBoolean); put("ignoreLocalDB", "nodb", Boolean::parseBoolean);
put("user", "u", identity()); put("user", "u", identity());
put("password", "pw", identity()); put("password", "pw", identity());
@ -62,10 +62,7 @@ public final class ClientConfig extends Config {
* @return {@code true} if the local database is to be ignored * @return {@code true} if the local database is to be ignored
* @since Envoy Client v0.3-alpha * @since Envoy Client v0.3-alpha
*/ */
public Boolean isIgnoreLocalDB() { public Boolean isIgnoreLocalDB() { return (Boolean) items.get("ignoreLocalDB").get(); }
final var ignoreLocalDB = items.get("ignoreLocalDB").get();
return ignoreLocalDB != null && (Boolean) ignoreLocalDB;
}
/** /**
* @return the user name * @return the user name

View File

@ -164,11 +164,11 @@ public final class Client implements Closeable {
// Process ProfilePicChanges // Process ProfilePicChanges
receiver.registerProcessor(ProfilePicChange.class, eventBus::dispatch); receiver.registerProcessor(ProfilePicChange.class, eventBus::dispatch);
// Process requests to not send anymore attachments as they will not be shown to // Process requests to not send any more attachments as they will not be shown to
// other users // other users
receiver.registerProcessor(NoAttachments.class, eventBus::dispatch); receiver.registerProcessor(NoAttachments.class, eventBus::dispatch);
// Process group creation rejections - they have been disabled on the server // Process group creation results - they might have been disabled on the server
receiver.registerProcessor(GroupCreationResult.class, eventBus::dispatch); receiver.registerProcessor(GroupCreationResult.class, eventBus::dispatch);
// Send event // Send event

View File

@ -67,7 +67,7 @@ public final class Receiver extends Thread {
// Catch LV encoding errors // Catch LV encoding errors
if (len != bytesRead) { if (len != bytesRead) {
// Server has stopped sending, i.e. because he went offline // Server has stopped sending, i.e. because he went offline
if (len == 0 && bytesRead == -1) { if (bytesRead == -1) {
isAlive = false; isAlive = false;
logger.log(Level.INFO, "Lost connection to the server. Exiting receiver..."); logger.log(Level.INFO, "Lost connection to the server. Exiting receiver...");
continue; continue;

View File

@ -132,7 +132,6 @@ public final class ChatScene implements Restorable {
private AudioRecorder recorder; private AudioRecorder recorder;
private boolean recording; private boolean recording;
private Attachment pendingAttachment; private Attachment pendingAttachment;
private boolean postingPermanentlyDisabled; private boolean postingPermanentlyDisabled;
private final SystemCommandsMap messageTextAreaCommands = new SystemCommandsMap(); private final SystemCommandsMap messageTextAreaCommands = new SystemCommandsMap();

View File

@ -11,10 +11,15 @@ import envoy.util.EnvoyLog;
/** /**
* Manages all application settings that are set during application startup by * Manages all application settings that are set during application startup by
* either loading them from the {@link Properties} file * either loading them from the {@link Properties} file (default values)
* {@code client.properties} or parsing them from the command line arguments of * {@code client.properties} or parsing them from the command line arguments of
* the application.<br> * the application.
* <br> * <p>
* All items inside the {@code Config} are supposed to either be supplied over
* default value or over command line argument. Developers that fail to provide
* default values will be greeted with an error message the next time they try
* to start Envoy...
* <p>
* Project: <strong>envoy-client</strong><br> * Project: <strong>envoy-client</strong><br>
* File: <strong>Config.java</strong><br> * File: <strong>Config.java</strong><br>
* Created: <strong>12 Oct 2019</strong><br> * Created: <strong>12 Oct 2019</strong><br>
@ -30,10 +35,10 @@ public class Config {
protected Config(String folderName) { protected Config(String folderName) {
final var rootDirectory = new File(System.getProperty("user.home"), folderName); final var rootDirectory = new File(System.getProperty("user.home"), folderName);
put("homeDirectory", "home", File::new, true); put("homeDirectory", "home", File::new);
((ConfigItem<File>) get("homeDirectory")).setValue(rootDirectory); ((ConfigItem<File>) get("homeDirectory")).setValue(rootDirectory);
put("fileLevelBarrier", "fb", Level::parse, true); put("fileLevelBarrier", "fb", Level::parse);
put("consoleLevelBarrier", "cb", Level::parse, true); put("consoleLevelBarrier", "cb", Level::parse);
} }
/** /**
@ -43,10 +48,8 @@ public class Config {
* @since Envoy Common v0.1-beta * @since Envoy Common v0.1-beta
*/ */
private void load(Properties properties) { private void load(Properties properties) {
items.entrySet() items.entrySet().stream().filter(e -> properties.containsKey(e.getKey()))
.stream() .forEach(e -> e.getValue().parse(properties.getProperty(e.getKey())));
.filter(e -> properties.containsKey(e.getKey()))
.forEach(e -> e.getValue().parse(properties.getProperty(e.getKey())));
} }
/** /**
@ -61,25 +64,31 @@ public class Config {
for (int i = 0; i < args.length; i++) for (int i = 0; i < args.length; i++)
for (final ConfigItem<?> item : items.values()) for (final ConfigItem<?> item : items.values())
if (args[i].startsWith("--")) { if (args[i].startsWith("--")) {
if (args[i].length() == 2) throw new IllegalStateException("Malformed command line argument at position " + i + ": " + args[i]); if (args[i].length() == 2)
throw new IllegalStateException(
"Malformed command line argument at position " + i + ": " + args[i]);
final String commandLong = args[i].substring(2); final String commandLong = args[i].substring(2);
if (item.getCommandLong().equals(commandLong)) { if (item.getCommandLong().equals(commandLong)) {
item.parse(args[++i]); item.parse(args[++i]);
break; break;
} }
} else if (args[i].startsWith("-")) { } else if (args[i].startsWith("-")) {
if (args[i].length() == 1) throw new IllegalStateException("Malformed command line argument at position " + i + ": " + args[i]); if (args[i].length() == 1)
throw new IllegalStateException(
"Malformed command line argument at position " + i + ": " + args[i]);
final String commandShort = args[i].substring(1); final String commandShort = args[i].substring(1);
if (item.getCommandShort().equals(commandShort)) { if (item.getCommandShort().equals(commandShort)) {
item.parse(args[++i]); item.parse(args[++i]);
break; break;
} }
} else throw new IllegalStateException("Malformed command line argument at position " + i + ": " + args[i]); } else
throw new IllegalStateException(
"Malformed command line argument at position " + i + ": " + args[i]);
} }
/** /**
* Supplies default values from the given .properties file and * Supplies default values from the given .properties file and parses the
* parses the configuration from an array of command line arguments. * configuration from an array of command line arguments.
* *
* @param declaringClass the class calling this method * @param declaringClass the class calling this method
* @param propertiesFilePath the path to where the .properties file can be found * @param propertiesFilePath the path to where the .properties file can be found
@ -93,37 +102,38 @@ public class Config {
* @since Envoy Common v0.1-beta * @since Envoy Common v0.1-beta
*/ */
public void loadAll(Class<?> declaringClass, String propertiesFilePath, String[] args) { public void loadAll(Class<?> declaringClass, String propertiesFilePath, String[] args) {
if (modificationDisabled) throw new IllegalStateException("Cannot change config after isInitialized has been called"); if (modificationDisabled)
throw new IllegalStateException("Cannot change config after isInitialized has been called");
// Load the defaults from the given .properties file first // Load the defaults from the given .properties file first
final var properties = new Properties(); final var properties = new Properties();
try { try {
properties.load(declaringClass.getClassLoader().getResourceAsStream(propertiesFilePath)); properties.load(declaringClass.getClassLoader().getResourceAsStream(propertiesFilePath));
} catch (final IOException e) { } catch (final IOException e) {
EnvoyLog.getLogger(Config.class).log(Level.SEVERE, "An error occurred when reading in the configuration: ", e); EnvoyLog.getLogger(Config.class).log(Level.SEVERE, "An error occurred when reading in the configuration: ",
e);
} }
load(properties); load(properties);
// Override configuration values with command line arguments // Override configuration values with command line arguments
if (args.length > 0) load(args); if (args.length > 0)
load(args);
// Check if all mandatory configuration values have been initialized // Check if all configuration values have been initialized
isInitialized(); isInitialized();
// Disable further editing of the config // Disable further editing of the config
modificationDisabled = true; modificationDisabled = true;
} }
/** /**
* @throws IllegalStateException if a mandatory {@link ConfigItem} has not been * @throws IllegalStateException if a {@link ConfigItem} has not been
* initialized * initialized
* @since Envoy Common v0.1-beta * @since Envoy Common v0.1-beta
*/ */
private void isInitialized() { private void isInitialized() {
if (items.values().stream().filter(ConfigItem::isMandatory).map(ConfigItem::get).anyMatch(Objects::isNull)) if (items.values().stream().map(ConfigItem::get).anyMatch(Objects::isNull))
throw new IllegalStateException("config item(s) has/ have not been initialized:" + items.values() throw new IllegalStateException("config item(s) has/ have not been initialized:"
.stream() + items.values().stream().filter(configItem -> configItem.get() == null)
.filter(configItem -> configItem.isMandatory() && configItem.get() == null) .map(ConfigItem::getCommandLong).collect(Collectors.toSet()));
.map(ConfigItem::getCommandLong)
.collect(Collectors.toSet()));
} }
/** /**
@ -131,28 +141,13 @@ public class Config {
* @return the config item with the specified name * @return the config item with the specified name
* @since Envoy Common v0.1-beta * @since Envoy Common v0.1-beta
*/ */
public ConfigItem<?> get(String name) { return items.get(name); } public ConfigItem<?> get(String name) {
return items.get(name);
/**
* Shorthand for <br>
* {@code items.put(commandName, new ConfigItem<>(commandName, commandShort, parseFunction, defaultValue, mandatory))}.
*
* @param <T> the type of the {@link ConfigItem}
* @param commandName the key for this config item as well as its long name
* @param commandShort the abbreviation of this config item
* @param parseFunction the {@code Function<String, T>} that parses the value
* from a string
* @param mandatory indicated that this config item must be initialized with
* a non-null value
* @since Envoy Common v0.2-beta
*/
protected <T> void put(String commandName, String commandShort, Function<String, T> parseFunction, boolean mandatory) {
items.put(commandName, new ConfigItem<>(commandName, commandShort, parseFunction, mandatory));
} }
/** /**
* Shorthand for <br> * Shorthand for <br>
* {@code put(commandName, commandShort, parseFunction, false)}. * {@code items.put(commandName, new ConfigItem<>(commandName, commandShort, parseFunction, defaultValue))}.
* *
* @param <T> the type of the {@link ConfigItem} * @param <T> the type of the {@link ConfigItem}
* @param commandName the key for this config item as well as its long name * @param commandName the key for this config item as well as its long name
@ -162,25 +157,30 @@ public class Config {
* @since Envoy Common v0.2-beta * @since Envoy Common v0.2-beta
*/ */
protected <T> void put(String commandName, String commandShort, Function<String, T> parseFunction) { protected <T> void put(String commandName, String commandShort, Function<String, T> parseFunction) {
put(commandName, commandShort, parseFunction, false); items.put(commandName, new ConfigItem<>(commandName, commandShort, parseFunction));
} }
/** /**
* @return the directory in which all local files are saves * @return the directory in which all local files are saves
* @since Envoy Client v0.2-beta * @since Envoy Client v0.2-beta
*/ */
public File getHomeDirectory() { return (File) items.get("homeDirectory").get(); } public File getHomeDirectory() {
return (File) items.get("homeDirectory").get();
}
/** /**
* @return the minimal {@link Level} to log inside the log file * @return the minimal {@link Level} to log inside the log file
* @since Envoy Client v0.2-beta * @since Envoy Client v0.2-beta
*/ */
public Level getFileLevelBarrier() { return (Level) items.get("fileLevelBarrier").get(); } public Level getFileLevelBarrier() {
return (Level) items.get("fileLevelBarrier").get();
}
/** /**
* @return the minimal {@link Level} to log inside the console * @return the minimal {@link Level} to log inside the console
* @since Envoy Client v0.2-beta * @since Envoy Client v0.2-beta
*/ */
public Level getConsoleLevelBarrier() { return (Level) items.get("consoleLevelBarrier").get(); } public Level getConsoleLevelBarrier() {
return (Level) items.get("consoleLevelBarrier").get();
}
} }

View File

@ -4,8 +4,10 @@ import java.util.function.Function;
/** /**
* Contains a single {@link Config} value as well as the corresponding command * Contains a single {@link Config} value as well as the corresponding command
* line arguments and its default value.<br> * line arguments and its default value.
* <br> * <p>
* All {@code ConfigItem}s are automatically mandatory.
* <p>
* Project: <strong>envoy-clientChess</strong><br> * Project: <strong>envoy-clientChess</strong><br>
* File: <strong>ConfigItem.javaEvent.java</strong><br> * File: <strong>ConfigItem.javaEvent.java</strong><br>
* Created: <strong>21.12.2019</strong><br> * Created: <strong>21.12.2019</strong><br>
@ -18,7 +20,6 @@ public final class ConfigItem<T> {
private final String commandLong, commandShort; private final String commandLong, commandShort;
private final Function<String, T> parseFunction; private final Function<String, T> parseFunction;
private final boolean mandatory;
private T value; private T value;
@ -29,28 +30,12 @@ public final class ConfigItem<T> {
* @param commandShort the short command line argument to set this value * @param commandShort the short command line argument to set this value
* @param parseFunction the {@code Function<String, T>} that parses the value * @param parseFunction the {@code Function<String, T>} that parses the value
* from a string * from a string
* @param mandatory indicated that this config item must be initialized with
* a non-null value
* @since Envoy Common v0.1-beta
*/
public ConfigItem(String commandLong, String commandShort, Function<String, T> parseFunction, boolean mandatory) {
this.commandLong = commandLong;
this.commandShort = commandShort;
this.parseFunction = parseFunction;
this.mandatory = mandatory;
}
/**
* Initializes an optional {@link ConfigItem} without a default value.
*
* @param commandLong the long command line argument to set this value
* @param commandShort the short command line argument to set this value
* @param parseFunction the {@code Function<String, T>} that parses the value
* from a string
* @since Envoy Common v0.1-beta * @since Envoy Common v0.1-beta
*/ */
public ConfigItem(String commandLong, String commandShort, Function<String, T> parseFunction) { public ConfigItem(String commandLong, String commandShort, Function<String, T> parseFunction) {
this(commandLong, commandShort, parseFunction, false); this.commandLong = commandLong;
this.commandShort = commandShort;
this.parseFunction = parseFunction;
} }
/** /**
@ -86,11 +71,4 @@ public final class ConfigItem<T> {
* @since Envoy Common v0.2-beta * @since Envoy Common v0.2-beta
*/ */
protected void setValue(T value) { this.value = value; } protected void setValue(T value) { this.value = value; }
/**
* @return {@code true} if this {@link ConfigItem} is mandatory for successful
* application initialization
* @since Envoy Common v0.1-beta
*/
public boolean isMandatory() { return mandatory; }
} }

View File

@ -11,15 +11,7 @@ package envoy.event;
* @author Leon Hofmeister * @author Leon Hofmeister
* @since Envoy Common v0.2-beta * @since Envoy Common v0.2-beta
*/ */
public class NoAttachments extends Event<Void> { public class NoAttachments extends Event.Valueless {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/**
* Creates a new {@code NoAttachments}.
*
* @since Envoy Common v0.2-beta
*/
public NoAttachments() { super(null); }
} }

View File

@ -24,17 +24,17 @@ public final class ServerConfig extends Config {
private ServerConfig() { private ServerConfig() {
super(".envoy-server"); super(".envoy-server");
put("enter-to-stop", "dev-stop", Boolean::parseBoolean, true); put("enter-to-stop", "dev-stop", Boolean::parseBoolean);
// parameters for issue reporting // parameters for issue reporting
put("issueCreationURL", "i-url", identity(), true); put("issueCreationURL", "i-url", identity());
put("issueAuthToken", "i-token", identity()); put("issueAuthToken", "i-token", identity());
put("userMadeLabel", "l-um", identity(), true); put("userMadeLabel", "l-um", identity());
put("bugLabel", "l-b", identity(), true); put("bugLabel", "l-b", identity());
put("featureLabel", "l-f", identity(), true); put("featureLabel", "l-f", identity());
// enabling/ disabling several processors // enabling/ disabling several processors
put("enableIssueReporting", "e-ir", Boolean::parseBoolean, true); put("enableIssueReporting", "e-ir", Boolean::parseBoolean);
put("enableGroups", "e-g", Boolean::parseBoolean, true); put("enableGroups", "e-g", Boolean::parseBoolean);
put("enableAttachments", "e-a", Boolean::parseBoolean, true); put("enableAttachments", "e-a", Boolean::parseBoolean);
} }
/** /**

View File

@ -13,4 +13,4 @@ featureLabel=119
#bugLabel="bug" #bugLabel="bug"
#featureLabel="feature" #featureLabel="feature"
consoleLevelBarrier=FINEST consoleLevelBarrier=FINEST
fileLevelBarrier=WARNING fileLevelBarrier=WARNING