Skip to content

Commit 6f587d6

Browse files
committed
Started to implement seeding and added accessible support to model bind transformer
1 parent 7e3d50d commit 6f587d6

File tree

10 files changed

+272
-13
lines changed

10 files changed

+272
-13
lines changed

src/main/java/org/javawebstack/framework/WebApplication.java

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package org.javawebstack.framework;
22

33
import com.github.javafaker.Faker;
4-
import org.javawebstack.command.CommandResult;
54
import org.javawebstack.command.CommandSystem;
65
import org.javawebstack.command.MultiCommand;
76
import org.javawebstack.framework.bind.ModelBindParamTransformer;
87
import org.javawebstack.framework.bind.ModelBindTransformer;
98
import org.javawebstack.framework.command.*;
109
import org.javawebstack.framework.config.Config;
1110
import org.javawebstack.framework.module.Module;
11+
import org.javawebstack.framework.seed.FileSeeder;
12+
import org.javawebstack.framework.seed.MergedSeeder;
13+
import org.javawebstack.framework.seed.Seeder;
1214
import org.javawebstack.framework.util.CORSPolicy;
1315
import org.javawebstack.framework.util.Crypt;
1416
import org.javawebstack.framework.util.MultipartPolicy;
@@ -22,7 +24,9 @@
2224
import org.javawebstack.orm.wrapper.SQLite;
2325

2426
import java.util.ArrayList;
27+
import java.util.HashMap;
2528
import java.util.List;
29+
import java.util.Map;
2630
import java.util.logging.Logger;
2731

2832
public abstract class WebApplication {
@@ -37,6 +41,7 @@ public abstract class WebApplication {
3741
private final List<Module> modules = new ArrayList<>();
3842
private final ModelBindParamTransformer modelBindParamTransformer = new ModelBindParamTransformer();
3943
private final CommandSystem commandSystem = new CommandSystem();
44+
private final Map<String, Seeder> seeders = new HashMap<>();
4045

4146
public WebApplication(){
4247
injector = new SimpleInjector();
@@ -105,13 +110,19 @@ public WebApplication(){
105110
modules.forEach(m -> m.setupCommands(this, commandSystem));
106111
commandSystem.addCommand("start", new StartCommand());
107112
commandSystem.addCommand("sh", new ShellCommand());
108-
commandSystem.addCommand("migrate", new MigrateCommand());
113+
commandSystem.addCommand("db", new MultiCommand()
114+
.add("migrate", new DBMigrateCommand())
115+
.add("seed", new DBSeedCommand())
116+
);
109117
commandSystem.addCommand("crypt", new MultiCommand()
110-
.add("generate", new CryptGenerateCommand())
111118
.add("encrypt", new CryptEncryptCommand())
112119
.add("decrypt", new CryptDecryptCommand())
113120
.add("hash", new CryptHashCommand())
114121
);
122+
commandSystem.addCommand("generate", new MultiCommand()
123+
.add("key", new GenerateKeyCommand())
124+
.add("seed", new GenerateSeedCommand())
125+
);
115126
}
116127

117128
public WebApplication addModule(Module module){
@@ -124,6 +135,27 @@ public WebApplication setModelBindTransformer(ModelBindTransformer transformer){
124135
return this;
125136
}
126137

138+
public WebApplication setAccessorAttribName(String name){
139+
modelBindParamTransformer.setAccessorAttribName(name);
140+
return this;
141+
}
142+
143+
public void addSeeder(String name, Seeder... seeder){
144+
if(seeder.length == 0)
145+
return;
146+
if(seeder.length > 1){
147+
addSeeder(name, new MergedSeeder(seeder));
148+
return;
149+
}
150+
seeders.put(name, seeder[0]);
151+
}
152+
153+
public Seeder getSeeder(String name){
154+
if(!seeders.containsKey(name))
155+
seeders.put(name, new FileSeeder(this, getClass().getClassLoader(), "seeds/"+name+".json"));
156+
return seeders.get(name);
157+
}
158+
127159
public Logger getLogger(){
128160
return logger;
129161
}

src/main/java/org/javawebstack/framework/bind/ModelBindParamTransformer.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010
public class ModelBindParamTransformer extends RouteParamTransformer {
1111

1212
private ModelBindTransformer transformer;
13+
private String accessorAttribName;
1314

1415
public ModelBindParamTransformer(){
15-
this.transformer = (repo, fieldName, source) -> repo.where(fieldName, source).get();
16+
this.transformer = (exchange, repo, fieldName, source) -> repo.accessible(accessorAttribName == null ? null : exchange.attrib(accessorAttribName)).where(fieldName, source).get();
1617
for(Class<? extends Model> model : ORM.getModels()){
1718
ModelBind[] binds = model.getDeclaredAnnotationsByType(ModelBind.class);
1819
if(binds.length == 0)
@@ -21,20 +22,21 @@ public ModelBindParamTransformer(){
2122
String fieldName = binds[0].field().length() > 0 ? binds[0].field() : repo.getInfo().getIdField();
2223
Class<?> fieldType = repo.getInfo().getField(fieldName).getType();
2324
String parent = "string";
24-
if(fieldType.equals(String.class))
25-
extend("string", binds[0].value(), repo::get);
2625
if(fieldType.equals(UUID.class))
2726
parent = "uuid";
2827
if(fieldType.equals(Integer.class))
2928
parent = "i+";
3029
if(fieldType.equals(Long.class))
3130
parent = "l+";
32-
extend(parent, binds[0].value(), source -> transformer.transform(repo, fieldName, source));
31+
extend(parent, binds[0].value(), (exchange, source) -> transformer.transform(exchange, repo, fieldName, source));
3332
}
3433
}
3534

3635
public void setTransformer(ModelBindTransformer transformer){
3736
this.transformer = transformer;
3837
}
3938

39+
public void setAccessorAttribName(String accessorAttribName) {
40+
this.accessorAttribName = accessorAttribName;
41+
}
4042
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package org.javawebstack.framework.bind;
22

3+
import org.javawebstack.httpserver.Exchange;
34
import org.javawebstack.orm.Repo;
45

56
public interface ModelBindTransformer {
6-
Object transform(Repo<?> repo, String fieldName, Object source);
7+
Object transform(Exchange exchange, Repo<?> repo, String fieldName, Object source);
78
}

src/main/java/org/javawebstack/framework/command/MigrateCommand.java renamed to src/main/java/org/javawebstack/framework/command/DBMigrateCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import java.util.List;
99
import java.util.Map;
1010

11-
public class MigrateCommand implements Command {
11+
public class DBMigrateCommand implements Command {
1212

1313
public CommandResult execute(CommandSystem commandSystem, List<String> args, Map<String, List<String>> params) {
1414
if(params.containsKey("a")){
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.javawebstack.framework.command;
2+
3+
import org.javawebstack.command.Command;
4+
import org.javawebstack.command.CommandResult;
5+
import org.javawebstack.command.CommandSystem;
6+
import org.javawebstack.framework.WebApplication;
7+
import org.javawebstack.injector.Inject;
8+
9+
import java.util.List;
10+
import java.util.Map;
11+
12+
public class DBSeedCommand implements Command {
13+
14+
@Inject
15+
WebApplication application;
16+
17+
public CommandResult execute(CommandSystem commandSystem, List<String> args, Map<String, List<String>> params) {
18+
if(args.size() == 0)
19+
return CommandResult.syntax("db seed [...seeds]");
20+
for(String name : args)
21+
application.getSeeder(name).seed();
22+
System.out.println("Seeding done!");
23+
return CommandResult.success();
24+
}
25+
}

src/main/java/org/javawebstack/framework/command/CryptGenerateCommand.java renamed to src/main/java/org/javawebstack/framework/command/GenerateKeyCommand.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,14 @@
33
import org.javawebstack.command.Command;
44
import org.javawebstack.command.CommandResult;
55
import org.javawebstack.command.CommandSystem;
6-
import org.javawebstack.framework.config.Config;
76
import org.javawebstack.framework.util.Crypt;
87
import org.javawebstack.framework.util.IO;
9-
import org.javawebstack.injector.Inject;
108

119
import java.io.IOException;
1210
import java.util.List;
1311
import java.util.Map;
1412

15-
public class CryptGenerateCommand implements Command {
13+
public class GenerateKeyCommand implements Command {
1614

1715
public CommandResult execute(CommandSystem commandSystem, List<String> args, Map<String, List<String>> params) {
1816
String[] lines;
@@ -41,7 +39,7 @@ public CommandResult execute(CommandSystem commandSystem, List<String> args, Map
4139
}
4240
try {
4341
IO.writeFile(".env", String.join("\n", lines));
44-
System.out.println("Generated a new key!");
42+
System.out.println("Key generated!");
4543
return CommandResult.success();
4644
} catch (IOException e) {
4745
return CommandResult.error(e);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package org.javawebstack.framework.command;
2+
3+
import org.javawebstack.command.Command;
4+
import org.javawebstack.command.CommandResult;
5+
import org.javawebstack.command.CommandSystem;
6+
import org.javawebstack.framework.seed.FileSeeder;
7+
import org.javawebstack.orm.Model;
8+
import org.javawebstack.orm.ORM;
9+
10+
import java.io.File;
11+
import java.util.ArrayList;
12+
import java.util.HashMap;
13+
import java.util.List;
14+
import java.util.Map;
15+
16+
public class GenerateSeedCommand implements Command {
17+
18+
public CommandResult execute(CommandSystem commandSystem, List<String> args, Map<String, List<String>> params) {
19+
if(args.size() < 1)
20+
return CommandResult.syntax("generate seed <name> [...models]");
21+
List<Class<? extends Model>> models = new ArrayList<>();
22+
Map<String, Class<? extends Model>> modelMap = new HashMap<>();
23+
ORM.getModels().forEach(m -> modelMap.put(m.getSimpleName(), m));
24+
for(int i=1; i<args.size(); i++){
25+
if(modelMap.containsKey(args.get(i)))
26+
models.add(modelMap.get(args.get(i)));
27+
}
28+
File seedsFolder = new File("src/main/resources/seeds");
29+
if(params.containsKey("module"))
30+
seedsFolder = new File(params.get("module").get(0)+"/src/main/resources/seeds");
31+
if(!seedsFolder.exists() && !seedsFolder.mkdirs())
32+
return CommandResult.error("Could not create seeds folder!");
33+
String name = args.get(0);
34+
String[] merge = params.containsKey("merge") ? params.get("merge").toArray(new String[0]) : new String[0];
35+
File seedFile = new File(seedsFolder, name + ".json");
36+
FileSeeder.create(seedFile, merge, models.toArray(new Class[0]));
37+
System.out.println("Seed generated!");
38+
return CommandResult.success();
39+
}
40+
41+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package org.javawebstack.framework.seed;
2+
3+
import org.javawebstack.framework.WebApplication;
4+
import org.javawebstack.framework.util.IO;
5+
import org.javawebstack.graph.*;
6+
import org.javawebstack.orm.Model;
7+
import org.javawebstack.orm.ORM;
8+
import org.javawebstack.orm.Repo;
9+
10+
import java.io.File;
11+
import java.io.IOException;
12+
import java.util.HashMap;
13+
import java.util.Map;
14+
15+
public class FileSeeder implements Seeder {
16+
17+
private static final GraphMapper mapper = new GraphMapper().setNamingPolicy(NamingPolicy.SNAKE_CASE);
18+
19+
private final WebApplication application;
20+
private final GraphArray array;
21+
22+
public FileSeeder(WebApplication application, GraphArray array){
23+
this.application = application;
24+
this.array = array;
25+
}
26+
27+
public FileSeeder(WebApplication application, File file){
28+
this(application, read(file));
29+
}
30+
31+
public FileSeeder(WebApplication application, String resource){
32+
this(application, ClassLoader.getSystemClassLoader(), resource);
33+
}
34+
35+
public FileSeeder(WebApplication application, ClassLoader loader, String resource){
36+
this(application, read(loader, resource));
37+
}
38+
39+
public void seed(){
40+
Map<String, Class<? extends Model>> modelMap = new HashMap<>();
41+
ORM.getModels().forEach(m -> modelMap.put(m.getSimpleName(), m));
42+
43+
for(GraphElement element : array){
44+
if(element.isObject()){
45+
GraphObject model = element.object();
46+
if(!model.has("type") || !model.get("type").isString() || !model.has("data"))
47+
continue;
48+
Class<? extends Model> modelType = modelMap.get(model.get("type").string());
49+
if(modelType == null)
50+
continue;
51+
if(model.get("data").isObject()){
52+
seed(modelType, model.get("data").object());
53+
} else if(model.get("data").isArray()){
54+
for(GraphElement e : model.get("data").array()){
55+
if(e.isObject())
56+
seed(modelType, e.object());
57+
}
58+
}
59+
}
60+
if(element.isString()){
61+
Seeder seeder = application.getSeeder(element.string());
62+
if(seeder != null)
63+
seeder.seed();
64+
}
65+
}
66+
}
67+
68+
private <T extends Model> void seed(Class<T> type, GraphObject object){
69+
T t = mapper.fromGraph(object, type);
70+
if(t != null)
71+
t.save();
72+
}
73+
74+
private static GraphArray read(File file){
75+
try {
76+
String[] spl = file.getName().split("\\.");
77+
switch (spl[spl.length-1]){
78+
case "yaml":
79+
case "yml":
80+
return GraphElement.fromYaml(IO.readTextFile(file)).array();
81+
default:
82+
return GraphArray.fromJson(IO.readJsonFile(file).getAsJsonArray());
83+
}
84+
} catch (IOException e) {
85+
return new GraphArray();
86+
}
87+
}
88+
89+
private static GraphArray read(ClassLoader loader, String fileName){
90+
try {
91+
String[] spl = fileName.split("\\.");
92+
switch (spl[spl.length-1]){
93+
case "yaml":
94+
case "yml":
95+
return GraphElement.fromYaml(IO.readTextResource(loader, fileName)).array();
96+
default:
97+
return GraphArray.fromJson(IO.readJsonResource(loader, fileName).getAsJsonArray());
98+
}
99+
} catch (IOException e) {
100+
return new GraphArray();
101+
}
102+
}
103+
104+
public static void create(File file, String[] merge, Class<? extends Model>... models){
105+
GraphArray root = new GraphArray();
106+
for(String m : merge)
107+
root.add(m);
108+
for(Class<? extends Model> model : models){
109+
GraphArray data = new GraphArray();
110+
Repo.get(model).all().forEach(e -> data.add(mapper.toGraph(e)));
111+
root.add(new GraphObject()
112+
.set("type", model.getSimpleName())
113+
.set("data", data)
114+
);
115+
}
116+
117+
try {
118+
String[] spl = file.getName().split("\\.");
119+
switch (spl[spl.length-1]){
120+
case "yaml":
121+
case "yml":
122+
IO.writeFile(file, root.toYaml(true));
123+
break;
124+
default:
125+
IO.writeFile(file, root.toJsonString(true));
126+
break;
127+
}
128+
}catch (IOException ignored){}
129+
}
130+
131+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.javawebstack.framework.seed;
2+
3+
import java.util.Arrays;
4+
import java.util.List;
5+
6+
public class MergedSeeder implements Seeder {
7+
8+
private final List<Seeder> seeders;
9+
10+
public MergedSeeder(List<Seeder> seeders){
11+
this.seeders = seeders;
12+
}
13+
14+
public MergedSeeder(Seeder... seeders){
15+
this(Arrays.asList(seeders));
16+
}
17+
18+
public void seed() {
19+
seeders.forEach(Seeder::seed);
20+
}
21+
22+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.javawebstack.framework.seed;
2+
3+
public interface Seeder {
4+
5+
void seed();
6+
7+
}

0 commit comments

Comments
 (0)