Skip to content

Commit 656f663

Browse files
committed
v1.4.0 release
1 parent 307c50a commit 656f663

14 files changed

+280
-109
lines changed

README.md

+9-10
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,15 @@ repositories {
1212
}
1313
1414
dependencies {
15-
implementation "net.mindustry_ddns:file-store:1.3.0"
15+
implementation "net.mindustry_ddns:file-store:1.4.0"
1616
}
1717
```
1818

1919
## Usage
2020

21-
This library is very easy to use. It provides a [property](https://github.com/matteobaccan/owner)
22-
and [json](https://github.com/google/gson) based file stores by default.
21+
This library is very easy to use. It provides a [property](https://github.com/matteobaccan/owner) and [json](https://github.com/google/gson) based file stores by default.
2322

24-
For example, let's say you have this `PersonConfig` config interface (uses property based file store):
23+
For example, let's say you have this `PersonConfig` config interface (uses the property based file store) :
2524

2625
```java
2726
public interface PersonConfig extends Accessible {
@@ -32,10 +31,10 @@ public interface PersonConfig extends Accessible {
3231
@DefaultValue("24")
3332
@key("person.age")
3433
int getAge();
35-
};
34+
}
3635
```
3736

38-
You'll just have to do:
37+
You'll just have to do :
3938

4039
```java
4140
FileStore<PersonConfig> store = new ConfigFileStore("./john.properties", PersonConfig.class);
@@ -47,13 +46,13 @@ If you call the `load()` method, it will try to load the file if it exists, othe
4746

4847
## Tips
4948

50-
If you are using the `JsonFileStore`, keep in mind that if the object hold by the store uses generics, you must use
51-
gson's `TypeToken` for the type such as:
49+
If you are using the `JsonFileStore`, keep in mind that if the object hold by the store uses generics, you must use gson's `TypeToken` for the type such as :
5250

5351
```java
54-
FileStore<List<Integer>> store = new JsonFileStore("./int-list.json", TypeToken.getParameterized(List.class, Integer.class).getType(), ArrayList::new);
52+
Type type = TypeToken.getParameterized(List.class, Integer.class).getType();
53+
FileStore<List<Integer>> store = new JsonFileStore("./int-list.json", type, ArrayList::new);
5554
```
5655

57-
As you can see, I don't use the raw `List.class` for the `Type`.
56+
As you can see, I don't use the raw `List.class` for the `type`.
5857
5958
> Not doing this may result in `ClassCastException` exceptions and other funny bugs.

src/main/java/net/mindustry_ddns/filestore/AbstractFileStore.java

+37-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package net.mindustry_ddns.filestore;
22

3-
import java.io.*;
4-
import java.util.function.*;
3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.util.function.Supplier;
56

67

78
/**
@@ -10,6 +11,7 @@
1011
* @param <T> the stored object type
1112
*/
1213
public abstract class AbstractFileStore<T> implements FileStore<T> {
14+
1315
private File file;
1416
private T object;
1517

@@ -18,6 +20,39 @@ protected AbstractFileStore(File file, Supplier<T> supplier) {
1820
this.object = supplier.get();
1921
}
2022

23+
protected AbstractFileStore(String path, Supplier<T> supplier) {
24+
this(new File(path), supplier);
25+
}
26+
27+
protected abstract void saveImpl() throws IOException;
28+
29+
protected abstract void loadImpl() throws IOException;
30+
31+
@SuppressWarnings("ResultOfMethodCallIgnored")
32+
@Override
33+
public void save() {
34+
getFile().getAbsoluteFile().getParentFile().mkdirs();
35+
36+
try {
37+
saveImpl();
38+
} catch (IOException e) {
39+
throw new RuntimeException("Unable to save the file store at " + getFile(), e);
40+
}
41+
}
42+
43+
@Override
44+
public void load() {
45+
if (!getFile().exists()) {
46+
save();
47+
} else {
48+
try {
49+
loadImpl();
50+
} catch (IOException e) {
51+
throw new RuntimeException("Unable to load the file store at " + getFile(), e);
52+
}
53+
}
54+
}
55+
2156
@Override
2257
public T get() {
2358
return object;

src/main/java/net/mindustry_ddns/filestore/ConfigFileStore.java

+17-23
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package net.mindustry_ddns.filestore;
22

3-
import net.mindustry_ddns.filestore.util.*;
4-
import org.aeonbits.owner.*;
3+
import net.mindustry_ddns.filestore.util.SingletonConfigFactory;
4+
import org.aeonbits.owner.Accessible;
5+
import org.aeonbits.owner.Config;
6+
import org.aeonbits.owner.ConfigFactory;
7+
import org.aeonbits.owner.Factory;
58

69
import java.io.*;
7-
import java.nio.charset.*;
8-
import java.util.*;
10+
import java.nio.charset.StandardCharsets;
11+
import java.util.Map;
12+
import java.util.Properties;
913

1014

1115
/**
@@ -22,6 +26,7 @@
2226
* @param <T> the stored config type
2327
*/
2428
public class ConfigFileStore<T extends Accessible> extends AbstractFileStore<T> {
29+
2530
private final Factory factory;
2631
private final Class<T> clazz;
2732

@@ -34,7 +39,7 @@ public class ConfigFileStore<T extends Accessible> extends AbstractFileStore<T>
3439
* @param imports imported properties for the initial value of the file store
3540
*/
3641
public ConfigFileStore(String path, Class<T> clazz, Factory factory, Map<?, ?>... imports) {
37-
super(new File(path), () -> factory.create(clazz, imports));
42+
super(path, () -> factory.create(clazz, imports));
3843
this.factory = factory;
3944
this.clazz = clazz;
4045
}
@@ -71,31 +76,20 @@ public static <T extends Accessible> ConfigFileStore<T> load(String path, Class<
7176
}
7277

7378
@Override
74-
@SuppressWarnings("ResultOfMethodCallIgnored")
75-
public void save() {
76-
getFile().getAbsoluteFile().getParentFile().mkdirs();
77-
78-
try (final Writer writer = new FileWriter(getFile(), StandardCharsets.UTF_8)) {
79+
protected void saveImpl() throws IOException {
80+
try (Writer writer = new FileWriter(getFile(), StandardCharsets.UTF_8)) {
7981
Properties properties = new Properties();
8082
get().fill(properties);
8183
properties.store(writer, null);
82-
} catch (IOException e) {
83-
throw new RuntimeException("Unable to save the config at " + getFile(), e);
8484
}
8585
}
8686

8787
@Override
88-
public void load() {
89-
if (!getFile().exists()) {
90-
save();
91-
} else {
92-
try (final Reader reader = new FileReader(getFile(), StandardCharsets.UTF_8)) {
93-
Properties properties = new Properties();
94-
properties.load(reader);
95-
set(factory.create(clazz, properties));
96-
} catch (IOException e) {
97-
throw new RuntimeException("Unable to load the config at " + getFile(), e);
98-
}
88+
public void loadImpl() throws IOException {
89+
try (Reader reader = new FileReader(getFile(), StandardCharsets.UTF_8)) {
90+
Properties properties = new Properties();
91+
properties.load(reader);
92+
set(factory.create(clazz, properties));
9993
}
10094
}
10195

src/main/java/net/mindustry_ddns/filestore/FileStore.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package net.mindustry_ddns.filestore;
22

3-
import java.io.*;
3+
import java.io.File;
44

55

66
/**
@@ -9,6 +9,7 @@
99
* @param <T> the stored object type
1010
*/
1111
public interface FileStore<T> {
12+
1213
/**
1314
* @return the stored object
1415
*/

src/main/java/net/mindustry_ddns/filestore/JsonFileStore.java

+13-20
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package net.mindustry_ddns.filestore;
22

3-
import com.google.gson.*;
3+
import com.google.gson.Gson;
4+
import com.google.gson.GsonBuilder;
5+
import com.google.gson.TypeAdapter;
6+
import com.google.gson.TypeAdapterFactory;
47

58
import java.io.*;
6-
import java.lang.reflect.*;
7-
import java.nio.charset.*;
8-
import java.util.function.*;
9+
import java.lang.reflect.Type;
10+
import java.nio.charset.StandardCharsets;
11+
import java.util.function.Supplier;
912

1013

1114
/**
@@ -22,6 +25,7 @@
2225
* @param <T> the stored object type
2326
*/
2427
public class JsonFileStore<T> extends AbstractFileStore<T> {
28+
2529
private final Type type;
2630
private final Gson gson;
2731

@@ -71,27 +75,16 @@ public static <T> JsonFileStore<T> load(String path, Type type, Supplier<T> supp
7175
}
7276

7377
@Override
74-
@SuppressWarnings("ResultOfMethodCallIgnored")
75-
public void save() {
76-
getFile().getAbsoluteFile().getParentFile().mkdirs();
77-
78-
try (final Writer writer = new FileWriter(getFile(), StandardCharsets.UTF_8)) {
78+
protected void saveImpl() throws IOException {
79+
try (Writer writer = new FileWriter(getFile(), StandardCharsets.UTF_8)) {
7980
gson.toJson(get(), type, writer);
80-
} catch (IOException e) {
81-
throw new RuntimeException("Unable to save the object at " + getFile(), e);
8281
}
8382
}
8483

8584
@Override
86-
public void load() {
87-
if (!getFile().exists()) {
88-
save();
89-
} else {
90-
try (final Reader reader = new FileReader(getFile(), StandardCharsets.UTF_8)) {
91-
set(gson.fromJson(reader, type));
92-
} catch (IOException e) {
93-
throw new RuntimeException("Unable to load the object at " + getFile(), e);
94-
}
85+
protected void loadImpl() throws IOException {
86+
try (Reader reader = new FileReader(getFile(), StandardCharsets.UTF_8)) {
87+
set(gson.fromJson(reader, type));
9588
}
9689
}
9790

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package net.mindustry_ddns.filestore;
2+
3+
import java.io.*;
4+
import java.nio.charset.StandardCharsets;
5+
import java.util.Map;
6+
import java.util.Properties;
7+
8+
/**
9+
* A simpler version of {@link ConfigFileStore} using a raw Property object.
10+
*/
11+
public class PropertiesFileStore extends AbstractFileStore<Properties> {
12+
13+
/**
14+
* Base constructor of the {@code PropertiesFileStore}.
15+
*
16+
* @param path the path of the file
17+
* @param imports a list of maps acting as default values, make sure the content only contains strings
18+
*/
19+
public PropertiesFileStore(String path, Map<?, ?>... imports) {
20+
super(new File(path), Properties::new);
21+
for (Map<?, ?> map : imports) get().putAll(map);
22+
}
23+
24+
/**
25+
* Static constructor that calls {@link #load()} directly after the {@code PropertiesFileStore} creation.
26+
*
27+
* @see PropertiesFileStore#PropertiesFileStore(String, Map[])
28+
*/
29+
public static PropertiesFileStore load(String path, Map<?, ?>... imports) {
30+
PropertiesFileStore store = new PropertiesFileStore(path, imports);
31+
store.load();
32+
return store;
33+
}
34+
35+
@Override
36+
protected void saveImpl() throws IOException {
37+
try (Writer writer = new FileWriter(getFile(), StandardCharsets.UTF_8)) {
38+
get().store(writer, null);
39+
}
40+
}
41+
42+
@Override
43+
protected void loadImpl() throws IOException {
44+
try (Reader reader = new FileReader(getFile(), StandardCharsets.UTF_8)) {
45+
get().clear();
46+
get().load(reader);
47+
}
48+
}
49+
}

src/main/java/net/mindustry_ddns/filestore/util/JsonArrayReader.java

+20-20
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11
package net.mindustry_ddns.filestore.util;
22

3-
import com.google.gson.*;
4-
import com.google.gson.stream.*;
5-
import net.mindustry_ddns.filestore.*;
3+
import com.google.gson.Gson;
4+
import com.google.gson.stream.JsonReader;
5+
import net.mindustry_ddns.filestore.JsonFileStore;
66

7-
import java.io.*;
8-
import java.lang.reflect.*;
9-
import java.nio.charset.*;
10-
import java.util.*;
7+
import java.io.Closeable;
8+
import java.io.FileReader;
9+
import java.io.IOException;
10+
import java.io.Reader;
11+
import java.lang.reflect.Type;
12+
import java.nio.charset.StandardCharsets;
13+
import java.util.Iterator;
14+
import java.util.NoSuchElementException;
1115

1216

1317
/**
1418
* An iterator backed by a {@link JsonReader} to read the elements of a json array.
1519
*
1620
* @param <E> the element type
1721
*/
18-
public class JsonArrayReader<E> implements Iterator<E>, Closeable{
22+
public class JsonArrayReader<E> implements Iterator<E>, Closeable {
23+
1924
private final JsonReader reader;
2025
private final Type type;
2126
private final Gson gson;
@@ -50,12 +55,12 @@ public JsonArrayReader(Reader reader, Type type) {
5055
* Create a {@code JsonArrayReader} that reads a json array from a file.
5156
*
5257
* @param path the path of the file where the json array is located
53-
* @param type the element type
54-
* @param gson the gson instance
58+
* @param type the element type
59+
* @param gson the gson instance
5560
*/
5661
public JsonArrayReader(String path, Type type, Gson gson) {
57-
try (Reader reader = new FileReader(path, StandardCharsets.UTF_8)) {
58-
this.reader = new JsonReader(reader);
62+
try {
63+
this.reader = new JsonReader(new FileReader(path, StandardCharsets.UTF_8));
5964
this.type = type;
6065
this.gson = gson;
6166
this.reader.beginArray();
@@ -90,9 +95,7 @@ public boolean hasNext() {
9095
if (!closed && reader.hasNext()) {
9196
return true;
9297
} else {
93-
if (!closed)
94-
reader.close();
95-
closed = true;
98+
close();
9699
return false;
97100
}
98101
} catch (IOException e) {
@@ -108,11 +111,8 @@ public boolean hasNext() {
108111
*/
109112
@Override
110113
public E next() {
111-
if (!closed) {
112-
return gson.fromJson(reader, type);
113-
} else {
114-
throw new NoSuchElementException("No more elements to read.");
115-
}
114+
if (hasNext()) return gson.fromJson(reader, type);
115+
throw new NoSuchElementException("No more elements to read.");
116116
}
117117

118118
@Override

0 commit comments

Comments
 (0)