Settings class implementation
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
$begingroup$
I have a settings.txt file with the following format:
property=value
another_property=value
category.sub_category.property_name=value
And a Settings class that reads the properties out of this file and uses reflection to assign values to the appropriate fields within the class and it's subclasses:
public final class Settings {
private Settings(){}
public static void loadSettingsFile(){
String dir = System.getProperty("user.dir") + "/settings.txt";
try {
List<String> lines = Files.readAllLines(Paths.get(dir));
for(String str : lines){
String property = str.split("=");
if(property.length == 2)
setProperty(property[0], property[1]);
}
} catch (Exception e) {
System.out.println("Settings file not found");
}
}
public static void setProperty(String name, String value){
try {
@SuppressWarnings("rawtypes")
Class target = Settings.class;
int lastDot = name.lastIndexOf('.');
if(lastDot != -1){
String classPath = Settings.class.getPackage().getName();
classPath += ".Settings$" + name.substring(0, lastDot).replace('.', '$');
target = Class.forName(classPath);
name = name.substring(lastDot + 1);
}
Field property = target.getField(name);
switch (property.getType().getName()) {
case "boolean":
property.set(null, value.equals("true"));
break;
case "int":
property.set(null, Integer.parseInt(value));
break;
case "double":
property.set(null, Double.parseDouble(value));
break;
default:
System.out.println("Could not set property '" + name + "' - unsupported field type: " + property.getType().getName());
return;
}
} catch (NoSuchFieldException | ClassNotFoundException e) {
System.out.println("Can't find or access property: " + name);
} catch (IllegalAccessException | SecurityException e) {
System.out.println("Can't set property '" + name + "' to " + value);
e.printStackTrace();
} catch (Exception e) {
System.out.println("Can't set property '" + name + "' to " + value);
}
}
/*------------------------------
settings fields start here
------------------------------*/
public static String mode = "training AI";
public static class map{
private map(){}
public static int width = 35;
public static int height = 30;
public static boolean generate_random_walls = false;
public static int random_walls_count = 10;
}
public static class training{
private training(){}
public static String algorithm = "genetic";
public static String custom_ann_file = "default.ann";
public static boolean override_ann_file_settings = false;
public static String sensory_input = "basic";
public static int smell_precision = 1;
public static boolean interfering_outputs = false;
// more settings...
}
// more subclasses containing settings...
}
I find it convenient to be able to access these settings OOP style from anywhere in my program, I prefer it over a Settings.get(String name) solution because that way the IDE shows me what settings there are so I don't have to remember all their names.
Are there any disadvantages to this solution?
Also I'm not sure about the naming convention, should I make the setProperty(...) method convert property names to match normal Java naming convention or is it ok to have the settings names match the settings file naming convention?
category.sub_category.property_name
convert name to:
Settings.Category.SubCategory.propertyName
java
$endgroup$
add a comment |
$begingroup$
I have a settings.txt file with the following format:
property=value
another_property=value
category.sub_category.property_name=value
And a Settings class that reads the properties out of this file and uses reflection to assign values to the appropriate fields within the class and it's subclasses:
public final class Settings {
private Settings(){}
public static void loadSettingsFile(){
String dir = System.getProperty("user.dir") + "/settings.txt";
try {
List<String> lines = Files.readAllLines(Paths.get(dir));
for(String str : lines){
String property = str.split("=");
if(property.length == 2)
setProperty(property[0], property[1]);
}
} catch (Exception e) {
System.out.println("Settings file not found");
}
}
public static void setProperty(String name, String value){
try {
@SuppressWarnings("rawtypes")
Class target = Settings.class;
int lastDot = name.lastIndexOf('.');
if(lastDot != -1){
String classPath = Settings.class.getPackage().getName();
classPath += ".Settings$" + name.substring(0, lastDot).replace('.', '$');
target = Class.forName(classPath);
name = name.substring(lastDot + 1);
}
Field property = target.getField(name);
switch (property.getType().getName()) {
case "boolean":
property.set(null, value.equals("true"));
break;
case "int":
property.set(null, Integer.parseInt(value));
break;
case "double":
property.set(null, Double.parseDouble(value));
break;
default:
System.out.println("Could not set property '" + name + "' - unsupported field type: " + property.getType().getName());
return;
}
} catch (NoSuchFieldException | ClassNotFoundException e) {
System.out.println("Can't find or access property: " + name);
} catch (IllegalAccessException | SecurityException e) {
System.out.println("Can't set property '" + name + "' to " + value);
e.printStackTrace();
} catch (Exception e) {
System.out.println("Can't set property '" + name + "' to " + value);
}
}
/*------------------------------
settings fields start here
------------------------------*/
public static String mode = "training AI";
public static class map{
private map(){}
public static int width = 35;
public static int height = 30;
public static boolean generate_random_walls = false;
public static int random_walls_count = 10;
}
public static class training{
private training(){}
public static String algorithm = "genetic";
public static String custom_ann_file = "default.ann";
public static boolean override_ann_file_settings = false;
public static String sensory_input = "basic";
public static int smell_precision = 1;
public static boolean interfering_outputs = false;
// more settings...
}
// more subclasses containing settings...
}
I find it convenient to be able to access these settings OOP style from anywhere in my program, I prefer it over a Settings.get(String name) solution because that way the IDE shows me what settings there are so I don't have to remember all their names.
Are there any disadvantages to this solution?
Also I'm not sure about the naming convention, should I make the setProperty(...) method convert property names to match normal Java naming convention or is it ok to have the settings names match the settings file naming convention?
category.sub_category.property_name
convert name to:
Settings.Category.SubCategory.propertyName
java
$endgroup$
add a comment |
$begingroup$
I have a settings.txt file with the following format:
property=value
another_property=value
category.sub_category.property_name=value
And a Settings class that reads the properties out of this file and uses reflection to assign values to the appropriate fields within the class and it's subclasses:
public final class Settings {
private Settings(){}
public static void loadSettingsFile(){
String dir = System.getProperty("user.dir") + "/settings.txt";
try {
List<String> lines = Files.readAllLines(Paths.get(dir));
for(String str : lines){
String property = str.split("=");
if(property.length == 2)
setProperty(property[0], property[1]);
}
} catch (Exception e) {
System.out.println("Settings file not found");
}
}
public static void setProperty(String name, String value){
try {
@SuppressWarnings("rawtypes")
Class target = Settings.class;
int lastDot = name.lastIndexOf('.');
if(lastDot != -1){
String classPath = Settings.class.getPackage().getName();
classPath += ".Settings$" + name.substring(0, lastDot).replace('.', '$');
target = Class.forName(classPath);
name = name.substring(lastDot + 1);
}
Field property = target.getField(name);
switch (property.getType().getName()) {
case "boolean":
property.set(null, value.equals("true"));
break;
case "int":
property.set(null, Integer.parseInt(value));
break;
case "double":
property.set(null, Double.parseDouble(value));
break;
default:
System.out.println("Could not set property '" + name + "' - unsupported field type: " + property.getType().getName());
return;
}
} catch (NoSuchFieldException | ClassNotFoundException e) {
System.out.println("Can't find or access property: " + name);
} catch (IllegalAccessException | SecurityException e) {
System.out.println("Can't set property '" + name + "' to " + value);
e.printStackTrace();
} catch (Exception e) {
System.out.println("Can't set property '" + name + "' to " + value);
}
}
/*------------------------------
settings fields start here
------------------------------*/
public static String mode = "training AI";
public static class map{
private map(){}
public static int width = 35;
public static int height = 30;
public static boolean generate_random_walls = false;
public static int random_walls_count = 10;
}
public static class training{
private training(){}
public static String algorithm = "genetic";
public static String custom_ann_file = "default.ann";
public static boolean override_ann_file_settings = false;
public static String sensory_input = "basic";
public static int smell_precision = 1;
public static boolean interfering_outputs = false;
// more settings...
}
// more subclasses containing settings...
}
I find it convenient to be able to access these settings OOP style from anywhere in my program, I prefer it over a Settings.get(String name) solution because that way the IDE shows me what settings there are so I don't have to remember all their names.
Are there any disadvantages to this solution?
Also I'm not sure about the naming convention, should I make the setProperty(...) method convert property names to match normal Java naming convention or is it ok to have the settings names match the settings file naming convention?
category.sub_category.property_name
convert name to:
Settings.Category.SubCategory.propertyName
java
$endgroup$
I have a settings.txt file with the following format:
property=value
another_property=value
category.sub_category.property_name=value
And a Settings class that reads the properties out of this file and uses reflection to assign values to the appropriate fields within the class and it's subclasses:
public final class Settings {
private Settings(){}
public static void loadSettingsFile(){
String dir = System.getProperty("user.dir") + "/settings.txt";
try {
List<String> lines = Files.readAllLines(Paths.get(dir));
for(String str : lines){
String property = str.split("=");
if(property.length == 2)
setProperty(property[0], property[1]);
}
} catch (Exception e) {
System.out.println("Settings file not found");
}
}
public static void setProperty(String name, String value){
try {
@SuppressWarnings("rawtypes")
Class target = Settings.class;
int lastDot = name.lastIndexOf('.');
if(lastDot != -1){
String classPath = Settings.class.getPackage().getName();
classPath += ".Settings$" + name.substring(0, lastDot).replace('.', '$');
target = Class.forName(classPath);
name = name.substring(lastDot + 1);
}
Field property = target.getField(name);
switch (property.getType().getName()) {
case "boolean":
property.set(null, value.equals("true"));
break;
case "int":
property.set(null, Integer.parseInt(value));
break;
case "double":
property.set(null, Double.parseDouble(value));
break;
default:
System.out.println("Could not set property '" + name + "' - unsupported field type: " + property.getType().getName());
return;
}
} catch (NoSuchFieldException | ClassNotFoundException e) {
System.out.println("Can't find or access property: " + name);
} catch (IllegalAccessException | SecurityException e) {
System.out.println("Can't set property '" + name + "' to " + value);
e.printStackTrace();
} catch (Exception e) {
System.out.println("Can't set property '" + name + "' to " + value);
}
}
/*------------------------------
settings fields start here
------------------------------*/
public static String mode = "training AI";
public static class map{
private map(){}
public static int width = 35;
public static int height = 30;
public static boolean generate_random_walls = false;
public static int random_walls_count = 10;
}
public static class training{
private training(){}
public static String algorithm = "genetic";
public static String custom_ann_file = "default.ann";
public static boolean override_ann_file_settings = false;
public static String sensory_input = "basic";
public static int smell_precision = 1;
public static boolean interfering_outputs = false;
// more settings...
}
// more subclasses containing settings...
}
I find it convenient to be able to access these settings OOP style from anywhere in my program, I prefer it over a Settings.get(String name) solution because that way the IDE shows me what settings there are so I don't have to remember all their names.
Are there any disadvantages to this solution?
Also I'm not sure about the naming convention, should I make the setProperty(...) method convert property names to match normal Java naming convention or is it ok to have the settings names match the settings file naming convention?
category.sub_category.property_name
convert name to:
Settings.Category.SubCategory.propertyName
java
java
asked 4 mins ago
potatopotato
29710
29710
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217419%2fsettings-class-implementation%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217419%2fsettings-class-implementation%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown