Compare commits
50 commits
Author | SHA1 | Date | |
---|---|---|---|
6975d6dad0 | |||
af3481fd4d | |||
cc6142562b | |||
01107c788f | |||
31fbc33fa6 | |||
a77404952f | |||
b82e91fefa | |||
9b41348588 | |||
97aa0ac391 | |||
0159f9c5fc | |||
6909ca513c | |||
a937f119ae | |||
da87230afc | |||
0afdb0b76e | |||
8c90fc60b9 | |||
a3c96aecc0 | |||
3a2e39f223 | |||
6f8a1b4ceb | |||
eba6a051fd | |||
89fd0553a2 | |||
ab03e73f58 | |||
|
f4ff094554 | ||
|
c7b9454ede | ||
|
ad430cb659 | ||
|
be289b8d7f | ||
|
800ad9a4e9 | ||
|
b800b88fb4 | ||
|
0c98fe6e2e | ||
|
9a19c54e34 | ||
|
8f37f9882b | ||
|
a231434ecd | ||
|
56ce2b7235 | ||
|
77f075abdc | ||
|
86e326db87 | ||
|
bd2cf6c26a | ||
|
784a51e75c | ||
|
4b1b83930e | ||
|
0111df23f5 | ||
|
5e3208c262 | ||
|
57132f320a | ||
|
5754720fe5 | ||
|
8941eac25c | ||
|
e6ad2822eb | ||
|
38f22e48b0 | ||
|
b0da444be1 | ||
|
3c17c823fe | ||
|
5d27475a9b | ||
|
813ebda6cb | ||
|
d2fd5aeff1 | ||
|
4befbd7147 |
144 changed files with 5693 additions and 5222 deletions
20
.classpath
20
.classpath
|
@ -1,24 +1,16 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||||
<attributes>
|
<classpathentry exported="true" kind="lib" path=".generated"/>
|
||||||
<attribute name="module" value="true"/>
|
|
||||||
</attributes>
|
|
||||||
</classpathentry>
|
|
||||||
<classpathentry kind="src" path="src"/>
|
<classpathentry kind="src" path="src"/>
|
||||||
<classpathentry kind="src" path="test"/>
|
<classpathentry kind="src" path="test"/>
|
||||||
|
<classpathentry exported="true" kind="lib" path="json-simple-1.1.1.jar"/>
|
||||||
<classpathentry exported="true" kind="lib" path="mysql-connector-java-8.0.28.jar"/>
|
<classpathentry exported="true" kind="lib" path="mysql-connector-java-8.0.28.jar"/>
|
||||||
|
<classpathentry exported="true" kind="lib" path="password4j-1.6.3.jar"/>
|
||||||
|
<classpathentry exported="true" kind="lib" path="slf4j-api-2.0.6.jar"/>
|
||||||
|
<classpathentry exported="true" kind="lib" path="jose4j-0.9.3.jar"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
|
||||||
<classpathentry kind="src" path=".apt_generated">
|
|
||||||
<attributes>
|
|
||||||
<attribute name="optional" value="true"/>
|
|
||||||
</attributes>
|
|
||||||
</classpathentry>
|
|
||||||
<classpathentry kind="lib" path="Treasure.jar"/>
|
<classpathentry kind="lib" path="Treasure.jar"/>
|
||||||
<classpathentry exported="true" kind="lib" path="JDA-5.0.0-beta.8-withDependencies.jar"/>
|
<classpathentry exported="true" kind="lib" path="JDA-5.0.0-beta.8-withDependencies.jar"/>
|
||||||
<classpathentry exported="true" kind="lib" path="PeerAtCodeFramework.jar"/>
|
|
||||||
<classpathentry exported="true" kind="lib" path="angus-activation-2.0.2.jar"/>
|
|
||||||
<classpathentry exported="true" kind="lib" path="jakarta.activation-api-2.1.3.jar"/>
|
|
||||||
<classpathentry exported="true" kind="lib" path="jakarta.mail-2.0.3.jar"/>
|
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
Binary file not shown.
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -2,8 +2,6 @@
|
||||||
bin/
|
bin/
|
||||||
.project
|
.project
|
||||||
config.txt
|
config.txt
|
||||||
config-test.txt
|
|
||||||
dist/
|
dist/
|
||||||
testApi/
|
testApi/
|
||||||
.apt_generated/*
|
.generated/*
|
||||||
/.apt_generated/
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
org.eclipse.jdt.apt.aptEnabled=true
|
org.eclipse.jdt.apt.aptEnabled=true
|
||||||
org.eclipse.jdt.apt.genSrcDir=.apt_generated
|
org.eclipse.jdt.apt.genSrcDir=.generated
|
||||||
org.eclipse.jdt.apt.genTestSrcDir=.apt_generated_tests
|
org.eclipse.jdt.apt.genTestSrcDir=.generated_tests
|
||||||
org.eclipse.jdt.apt.processorOptions/treasure.source=%sourcepath%
|
org.eclipse.jdt.apt.processorOptions/treasure.source=%sourcepath%
|
||||||
org.eclipse.jdt.apt.reconcileEnabled=true
|
org.eclipse.jdt.apt.reconcileEnabled=true
|
||||||
|
|
Binary file not shown.
BIN
Treasure.jar
BIN
Treasure.jar
Binary file not shown.
Binary file not shown.
|
@ -1,127 +0,0 @@
|
||||||
DROP TABLE IF EXISTS `containsTags`;
|
|
||||||
DROP TABLE IF EXISTS `tags`;
|
|
||||||
DROP TABLE IF EXISTS `containsBadges`;
|
|
||||||
DROP TABLE IF EXISTS `badges`;
|
|
||||||
DROP TABLE IF EXISTS `containsGroups`;
|
|
||||||
DROP TABLE IF EXISTS `nextPart`;
|
|
||||||
DROP TABLE IF EXISTS `groups`;
|
|
||||||
DROP TABLE IF EXISTS `completions`;
|
|
||||||
DROP TABLE IF EXISTS `players`;
|
|
||||||
DROP TABLE IF EXISTS `puzzles`;
|
|
||||||
DROP TABLE IF EXISTS `chapters`;
|
|
||||||
|
|
||||||
CREATE TABLE `players` (
|
|
||||||
`id_player` int(11) NOT NULL AUTO_INCREMENT,
|
|
||||||
`pseudo` varchar(100) NOT NULL,
|
|
||||||
`email` varchar(100) NOT NULL,
|
|
||||||
`passwd` varchar(150) NOT NULL,
|
|
||||||
`firstname` varchar(100) NOT NULL,
|
|
||||||
`lastname` varchar(100) NOT NULL,
|
|
||||||
`description` varchar(200) DEFAULT NULL,
|
|
||||||
`avatar` blob DEFAULT NULL,
|
|
||||||
PRIMARY KEY (`id_player`)
|
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
||||||
|
|
||||||
CREATE TABLE badges (
|
|
||||||
id_badge int(11) NOT NULL AUTO_INCREMENT,
|
|
||||||
name varchar(50) NOT NULL,
|
|
||||||
logo mediumblob DEFAULT NULL,
|
|
||||||
level int(11) DEFAULT 1,
|
|
||||||
PRIMARY KEY (id_badge)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE `chapters` (
|
|
||||||
`id_chapter` int(11) NOT NULL AUTO_INCREMENT,
|
|
||||||
`name` varchar(150) NOT NULL,
|
|
||||||
`start_date` datetime DEFAULT NULL,
|
|
||||||
`end_date` datetime DEFAULT NULL,
|
|
||||||
PRIMARY KEY (`id_chapter`)
|
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
||||||
|
|
||||||
CREATE TABLE `puzzles` (
|
|
||||||
`id_puzzle` int(11) NOT NULL AUTO_INCREMENT,
|
|
||||||
`name` varchar(150) NOT NULL,
|
|
||||||
`content` text NOT NULL,
|
|
||||||
`soluce` blob NOT NULL,
|
|
||||||
`verify` text DEFAULT NULL,
|
|
||||||
`score_max` int(11) NOT NULL,
|
|
||||||
`fk_chapter` int(11) NOT NULL,
|
|
||||||
PRIMARY KEY (`id_puzzle`),
|
|
||||||
KEY `fk_chapter` (`fk_chapter`),
|
|
||||||
CONSTRAINT `puzzles_ibfk_1` FOREIGN KEY (`fk_chapter`) REFERENCES `chapters` (`id_chapter`)
|
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE `groups` (
|
|
||||||
`id_group` int(11) NOT NULL AUTO_INCREMENT,
|
|
||||||
`name` varchar(150) DEFAULT NULL,
|
|
||||||
`fk_chapter` int(11) DEFAULT NULL,
|
|
||||||
`fk_puzzle` int(11) DEFAULT NULL,
|
|
||||||
PRIMARY KEY (`id_group`),
|
|
||||||
KEY `fk_chapter` (`fk_chapter`),
|
|
||||||
KEY `fk_puzzle` (`fk_puzzle`),
|
|
||||||
CONSTRAINT `groups_ibfk_1` FOREIGN KEY (`fk_chapter`) REFERENCES `chapters` (`id_chapter`),
|
|
||||||
CONSTRAINT `groups_ibfk_2` FOREIGN KEY (`fk_puzzle`) REFERENCES `puzzles` (`id_puzzle`)
|
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE `nextPart` (
|
|
||||||
`origin` int(11) NOT NULL,
|
|
||||||
`next` int(11) NOT NULL,
|
|
||||||
PRIMARY KEY (`origin`,`next`),
|
|
||||||
KEY `next` (`next`),
|
|
||||||
CONSTRAINT `nextPart_ibfk_1` FOREIGN KEY (`origin`) REFERENCES `puzzles` (`id_puzzle`),
|
|
||||||
CONSTRAINT `nextPart_ibfk_2` FOREIGN KEY (`next`) REFERENCES `puzzles` (`id_puzzle`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE `completions` (
|
|
||||||
`id_completion` int(11) NOT NULL AUTO_INCREMENT,
|
|
||||||
`fk_puzzle` int(11) NOT NULL,
|
|
||||||
`fk_player` int(11) NOT NULL,
|
|
||||||
`tries` int(11) DEFAULT 0,
|
|
||||||
`code` blob DEFAULT NULL,
|
|
||||||
`score` int(11) DEFAULT 0,
|
|
||||||
`fileName` varchar(100) DEFAULT NULL,
|
|
||||||
PRIMARY KEY (`id_completion`),
|
|
||||||
KEY `fk_puzzle` (`fk_puzzle`),
|
|
||||||
KEY `fk_player` (`fk_player`),
|
|
||||||
CONSTRAINT `completions_ibfk_1` FOREIGN KEY (`fk_puzzle`) REFERENCES `puzzles` (`id_puzzle`),
|
|
||||||
CONSTRAINT `completions_ibfk_2` FOREIGN KEY (`fk_player`) REFERENCES `players` (`id_player`)
|
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
||||||
|
|
||||||
CREATE TABLE `tags` (
|
|
||||||
`id_tag` int(11) NOT NULL AUTO_INCREMENT,
|
|
||||||
`name` varchar(50) NOT NULL,
|
|
||||||
PRIMARY KEY (`id_tag`)
|
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
||||||
|
|
||||||
CREATE TABLE `containsBadges` (
|
|
||||||
`fk_player` int(11) NOT NULL,
|
|
||||||
`fk_badge` int(11) NOT NULL,
|
|
||||||
PRIMARY KEY (`fk_player`,`fk_badge`),
|
|
||||||
KEY `fk_badge` (`fk_badge`),
|
|
||||||
CONSTRAINT `containsBadges_ibfk_1` FOREIGN KEY (`fk_player`) REFERENCES `players` (`id_player`),
|
|
||||||
CONSTRAINT `containsBadges_ibfk_2` FOREIGN KEY (`fk_badge`) REFERENCES `badges` (`id_badge`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
||||||
|
|
||||||
CREATE TABLE `containsGroups` (
|
|
||||||
`fk_player` int(11) NOT NULL,
|
|
||||||
`fk_group` int(11) NOT NULL,
|
|
||||||
PRIMARY KEY (`fk_player`,`fk_group`),
|
|
||||||
KEY `fk_group` (`fk_group`),
|
|
||||||
CONSTRAINT `containsGroups_ibfk_1` FOREIGN KEY (`fk_player`) REFERENCES `players` (`id_player`),
|
|
||||||
CONSTRAINT `containsGroups_ibfk_2` FOREIGN KEY (`fk_group`) REFERENCES `groups` (`id_group`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
||||||
|
|
||||||
CREATE TABLE `containsTags` (
|
|
||||||
`fk_tag` int(11) NOT NULL,
|
|
||||||
`fk_puzzle` int(11) NOT NULL,
|
|
||||||
PRIMARY KEY (`fk_tag`,`fk_puzzle`),
|
|
||||||
KEY `fk_puzzle` (`fk_puzzle`),
|
|
||||||
CONSTRAINT `containsTags_ibfk_1` FOREIGN KEY (`fk_tag`) REFERENCES `tags` (`id_tag`),
|
|
||||||
CONSTRAINT `containsTags_ibfk_2` FOREIGN KEY (`fk_puzzle`) REFERENCES `puzzles` (`id_puzzle`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
||||||
|
|
||||||
INSERT INTO chapters (id_chapter, name) VALUES (1, 'chapter 1');
|
|
||||||
INSERT INTO players (pseudo, email, passwd,firstname,lastname) VALUES ('userTest', 'test@peerat.dev', '$argon2id$v=19$m=15360,t=2,p=1$$cAQwfs30Bf2rQGj86bpz7i59TlsuOFPiXeNpLlVu4AY', 'a','b')
|
|
Binary file not shown.
Binary file not shown.
BIN
jose4j-0.9.3.jar
Normal file
BIN
jose4j-0.9.3.jar
Normal file
Binary file not shown.
BIN
json-simple-1.1.1.jar
Normal file
BIN
json-simple-1.1.1.jar
Normal file
Binary file not shown.
BIN
password4j-1.6.3.jar
Normal file
BIN
password4j-1.6.3.jar
Normal file
Binary file not shown.
|
@ -1,6 +0,0 @@
|
||||||
/chapter/0
|
|
||||||
GET
|
|
||||||
Authorization: Bearer <token:test@peerat.dev>
|
|
||||||
|
|
||||||
|
|
||||||
400
|
|
|
@ -1,8 +0,0 @@
|
||||||
/chapters
|
|
||||||
GET
|
|
||||||
Authorization: Bearer <token:test@peerat.dev>
|
|
||||||
|
|
||||||
|
|
||||||
200
|
|
||||||
|
|
||||||
[]
|
|
|
@ -1,8 +0,0 @@
|
||||||
/leaderboard/
|
|
||||||
GET
|
|
||||||
Authorization: Bearer <token:test@peerat.dev>
|
|
||||||
|
|
||||||
|
|
||||||
200
|
|
||||||
|
|
||||||
[]
|
|
|
@ -1,6 +0,0 @@
|
||||||
/puzzle/0
|
|
||||||
GET
|
|
||||||
Authorization: Bearer <token:test@peerat.dev>
|
|
||||||
|
|
||||||
|
|
||||||
400
|
|
|
@ -1,6 +0,0 @@
|
||||||
/admin/chapter/0
|
|
||||||
GET
|
|
||||||
Authorization: Bearer <token:test@peerat.dev>
|
|
||||||
|
|
||||||
|
|
||||||
401
|
|
BIN
slf4j-api-2.0.6.jar
Normal file
BIN
slf4j-api-2.0.6.jar
Normal file
Binary file not shown.
|
@ -1,4 +1,4 @@
|
||||||
package dev.peerat.backend;
|
package be.jeffcheasey88.peeratcode;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
|
@ -7,12 +7,8 @@ import java.io.FileReader;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
import dev.peerat.backend.utils.Mail;
|
|
||||||
|
|
||||||
public class Configuration {
|
public class Configuration {
|
||||||
|
|
||||||
private boolean prod;
|
|
||||||
|
|
||||||
private String db_host;
|
private String db_host;
|
||||||
private int db_port;
|
private int db_port;
|
||||||
private String db_user;
|
private String db_user;
|
||||||
|
@ -33,21 +29,6 @@ public class Configuration {
|
||||||
|
|
||||||
private int groupJoinMinutes;
|
private int groupJoinMinutes;
|
||||||
private String groupQuitMinutes;
|
private String groupQuitMinutes;
|
||||||
private int groupMaxPlayers;
|
|
||||||
|
|
||||||
private String mailUsername;
|
|
||||||
private String mailPassword;
|
|
||||||
private String mailSmtpHost;
|
|
||||||
private int mailSmtpPort;
|
|
||||||
private String mailFromAddress;
|
|
||||||
|
|
||||||
private String git_token;
|
|
||||||
|
|
||||||
private String jwt_key;
|
|
||||||
|
|
||||||
private String sql_folder;
|
|
||||||
|
|
||||||
private int event_chapter;
|
|
||||||
|
|
||||||
private File _file;
|
private File _file;
|
||||||
|
|
||||||
|
@ -56,29 +37,20 @@ public class Configuration {
|
||||||
System.out.println("Config on " + _file.getAbsolutePath());
|
System.out.println("Config on " + _file.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> Configuration addDefaultValue(String name, T value) throws Exception{
|
public void load() throws Exception {
|
||||||
if(value == null) throw new IllegalArgumentException("Value cannot be null");
|
if (!this._file.exists())
|
||||||
Field field = getClass().getDeclaredField(name);
|
return;
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(this, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Configuration load() throws Exception{
|
|
||||||
if(!this._file.exists()) return this;
|
|
||||||
BufferedReader reader = new BufferedReader(new FileReader(this._file));
|
BufferedReader reader = new BufferedReader(new FileReader(this._file));
|
||||||
String line;
|
String line;
|
||||||
while((line = reader.readLine()) != null){
|
while ((line = reader.readLine()) != null) {
|
||||||
int index = line.indexOf('=');
|
String[] split = line.split("=");
|
||||||
String key = line.substring(0, index);
|
Field field = getClass().getDeclaredField(split[0]);
|
||||||
String value = line.substring(index+1);
|
if (field == null)
|
||||||
Field field = getClass().getDeclaredField(key);
|
continue;
|
||||||
if(field == null) continue;
|
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
injectValue(field, value);
|
injectValue(field, split[1]);
|
||||||
}
|
}
|
||||||
reader.close();
|
reader.close();
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void injectValue(Field field, String value) throws IllegalAccessException {
|
private void injectValue(Field field, String value) throws IllegalAccessException {
|
||||||
|
@ -123,70 +95,70 @@ public class Configuration {
|
||||||
public void save() throws Exception {
|
public void save() throws Exception {
|
||||||
if (!_file.exists()) {
|
if (!_file.exists()) {
|
||||||
File parent = _file.getParentFile();
|
File parent = _file.getParentFile();
|
||||||
if(!parent.exists()) parent.mkdirs();
|
if (!parent.exists())
|
||||||
|
parent.mkdirs();
|
||||||
_file.createNewFile();
|
_file.createNewFile();
|
||||||
}
|
}
|
||||||
Field[] fields = getClass().getDeclaredFields();
|
Field[] fields = getClass().getDeclaredFields();
|
||||||
BufferedWriter writer = new BufferedWriter(new FileWriter(_file));
|
BufferedWriter writer = new BufferedWriter(new FileWriter(_file));
|
||||||
for(Field field : fields){
|
for (Field field : fields) {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
if(field.getName().startsWith("_")) continue;
|
if (field.getName().startsWith("_"))
|
||||||
|
continue;
|
||||||
Object value = field.get(this);
|
Object value = field.get(this);
|
||||||
writer.write(field.getName() + "=" + value+"\n");
|
writer.write(field.getName() + "=" + value);
|
||||||
}
|
}
|
||||||
writer.flush();
|
writer.flush();
|
||||||
writer.close();
|
writer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isProduction(){
|
public String getDbHost() {
|
||||||
return this.prod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDbHost(){
|
|
||||||
return this.db_host;
|
return this.db_host;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDbPort(){
|
public int getDbPort() {
|
||||||
return this.db_port;
|
return this.db_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDbUser(){
|
public String getDbUser() {
|
||||||
return this.db_user;
|
return this.db_user;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDbDatabase(){
|
public String getDbDatabase() {
|
||||||
return this.db_database;
|
return this.db_database;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDbPassword(){
|
public String getDbPassword() {
|
||||||
return this.db_password;
|
return this.db_password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSslKeystore(){
|
public String getSslKeystore() {
|
||||||
return this.ssl_keystore;
|
return this.ssl_keystore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTokenIssuer(){
|
public String getTokenIssuer() {
|
||||||
return this.token_issuer;
|
return this.token_issuer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTokenExpiration(){
|
public int getTokenExpiration() {
|
||||||
return this.token_expiration;
|
return this.token_expiration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSslKeystorePasswd(){
|
public String getSslKeystorePasswd() {
|
||||||
return this.ssl_keystorePasswd;
|
return this.ssl_keystorePasswd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTcpPort(){
|
public int getTcpPort() {
|
||||||
return this.tcp_port;
|
return this.tcp_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean useSsl(){
|
public boolean useSsl() {
|
||||||
return this.use_ssl;
|
return this.use_ssl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsersFiles(){
|
public String getUsersFiles() {
|
||||||
|
if (users_files == null || users_files.trim().isEmpty())
|
||||||
|
users_files = "/tmp/users_files";
|
||||||
return users_files;
|
return users_files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,37 +173,4 @@ public class Configuration {
|
||||||
public String getGroupQuitMinutes(){
|
public String getGroupQuitMinutes(){
|
||||||
return this.groupQuitMinutes;
|
return this.groupQuitMinutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGroupMaxPlayers(){
|
|
||||||
return this.groupMaxPlayers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mail getMail(){
|
|
||||||
return new Mail(
|
|
||||||
this.mailUsername,
|
|
||||||
this.mailPassword,
|
|
||||||
this.mailSmtpHost,
|
|
||||||
this.mailSmtpPort,
|
|
||||||
this.mailFromAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGitToken(){
|
|
||||||
return this.git_token;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getJwtKey(){
|
|
||||||
return this.jwt_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setJwtKey(String key){
|
|
||||||
this.jwt_key = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSqlFolder(){
|
|
||||||
return this.sql_folder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getEventChapter(){
|
|
||||||
return this.event_chapter;
|
|
||||||
}
|
|
||||||
}
|
}
|
136
src/be/jeffcheasey88/peeratcode/Main.java
Normal file
136
src/be/jeffcheasey88/peeratcode/Main.java
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
package be.jeffcheasey88.peeratcode;
|
||||||
|
|
||||||
|
import static be.jeffcheasey88.peeratcode.framework.RequestType.OPTIONS;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLServerSocket;
|
||||||
|
import javax.net.ssl.SSLServerSocketFactory;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Client;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Locker;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Router;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Completion;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Group;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.BadgeDetails;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.ChapterElement;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.ChapterList;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.DynamicLeaderboard;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.Leaderboard;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.Login;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.PlayerDetails;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.PuzzleElement;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.PuzzleResponse;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.Register;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.Result;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.groups.GroupCreate;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.groups.GroupJoin;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.groups.GroupList;
|
||||||
|
import be.jeffcheasey88.peeratcode.routes.groups.GroupQuit;
|
||||||
|
|
||||||
|
public class Main{
|
||||||
|
public static void main(String[] args) throws Exception{
|
||||||
|
Configuration config = new Configuration("config.txt");
|
||||||
|
config.load();
|
||||||
|
|
||||||
|
Class.forName("com.mysql.cj.jdbc.Driver");
|
||||||
|
|
||||||
|
Router router = new Router(new DatabaseRepository(config), config.getTokenIssuer(),
|
||||||
|
config.getTokenExpiration());
|
||||||
|
|
||||||
|
router.setDefault((matcher, user, reader, writer) -> {
|
||||||
|
writer.response(404, "Access-Control-Allow-Origin: *");
|
||||||
|
writer.write("404 not Found.\n");
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
router.register(new Response(){
|
||||||
|
@Route(path = "^(.*)$", type = OPTIONS)
|
||||||
|
@Override
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *",
|
||||||
|
"Access-Control-Allow-Methods: *", "Access-Control-Allow-Headers: *");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
initRoutes(router, config);
|
||||||
|
|
||||||
|
// RouteExtracter extracter = new RouteExtracter(router);
|
||||||
|
// extracter.extract();
|
||||||
|
|
||||||
|
startWebServer(config, router);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void initRoutes(Router router, Configuration config){
|
||||||
|
router.register(new ChapterElement(router.getDataBase()));
|
||||||
|
router.register(new ChapterList(router.getDataBase()));
|
||||||
|
router.register(new PuzzleElement(router.getDataBase()));
|
||||||
|
router.register(new Register(router.getDataBase(), router, config.getUsersFiles()));
|
||||||
|
router.register(new Login(router.getDataBase(), router));
|
||||||
|
router.register(new Result(router.getDataBase()));
|
||||||
|
router.register(new Leaderboard(router.getDataBase()));
|
||||||
|
router.register(new PlayerDetails(router.getDataBase()));
|
||||||
|
router.register(new BadgeDetails(router.getDataBase()));
|
||||||
|
|
||||||
|
Locker<Group> groupLock = new Locker<>();
|
||||||
|
router.register(new GroupCreate(router.getDataBase(), groupLock, config.getGroupJoinMinutes()));
|
||||||
|
|
||||||
|
DynamicLeaderboard dlb = new DynamicLeaderboard(router.getDataBase());
|
||||||
|
router.register(dlb);
|
||||||
|
|
||||||
|
Locker<Completion> leaderboard = dlb.getLocker();
|
||||||
|
|
||||||
|
router.register(new PuzzleResponse(router.getDataBase(), config.getUsersFiles(), leaderboard));
|
||||||
|
router.register(new GroupList(router.getDataBase()));
|
||||||
|
router.register(new GroupJoin(router.getDataBase(), config.getGroupJoinMinutes(), config.getGroupQuitMinutes(), leaderboard));
|
||||||
|
router.register(new GroupQuit(router.getDataBase(), config.getGroupJoinMinutes(), leaderboard));
|
||||||
|
|
||||||
|
// Bot bot = new Bot(config, router.getDataBase(), groupLock);
|
||||||
|
// bot.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void startWebServer(Configuration config, Router router) throws IOException {
|
||||||
|
if (config.useSsl()) { // Not needed with the use of a proxy
|
||||||
|
SSLServerSocket server = null;
|
||||||
|
try {
|
||||||
|
System.setProperty("javax.net.ssl.keyStore", config.getSslKeystore());
|
||||||
|
System.setProperty("javax.net.ssl.keyStorePassword", config.getSslKeystorePasswd());
|
||||||
|
|
||||||
|
SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
|
||||||
|
server = (SSLServerSocket) ssf.createServerSocket(config.getTcpPort());
|
||||||
|
|
||||||
|
while (!server.isClosed()) {
|
||||||
|
Socket socket = server.accept();
|
||||||
|
Client client = new Client(socket, router);
|
||||||
|
client.start();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (server != null) {
|
||||||
|
server.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try (ServerSocket server = new ServerSocket(config.getTcpPort())) {
|
||||||
|
while (!server.isClosed()) {
|
||||||
|
Socket socket = server.accept();
|
||||||
|
Client client = new Client(socket, router);
|
||||||
|
client.start();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
package dev.peerat.backend.bonus.discord;
|
package be.jeffcheasey88.peeratcode.bonus.discord;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import dev.peerat.backend.Configuration;
|
import be.jeffcheasey88.peeratcode.Configuration;
|
||||||
import dev.peerat.backend.model.Group;
|
import be.jeffcheasey88.peeratcode.framework.Locker;
|
||||||
import dev.peerat.backend.repository.DatabaseRepository;
|
import be.jeffcheasey88.peeratcode.framework.Locker.Key;
|
||||||
import dev.peerat.framework.Locker;
|
import be.jeffcheasey88.peeratcode.model.Group;
|
||||||
import dev.peerat.framework.Locker.Key;
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
import net.dv8tion.jda.api.JDA;
|
import net.dv8tion.jda.api.JDA;
|
||||||
import net.dv8tion.jda.api.JDABuilder;
|
import net.dv8tion.jda.api.JDABuilder;
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
@ -38,7 +38,7 @@ public class Bot extends Thread{
|
||||||
|
|
||||||
locker.init(key);
|
locker.init(key);
|
||||||
|
|
||||||
List<Group> groups = this.repo.getGroupRepository().getAllGroups();
|
List<Group> groups = this.repo.getAllGroups();
|
||||||
for(Group group : groups){
|
for(Group group : groups){
|
||||||
Integer chapter = group.getLinkToChapter();
|
Integer chapter = group.getLinkToChapter();
|
||||||
// Integer puzzle = group.getLinkToPuzzle();
|
// Integer puzzle = group.getLinkToPuzzle();
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.peerat.backend.bonus.extract;
|
package be.jeffcheasey88.peeratcode.bonus.extract;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Repeatable;
|
import java.lang.annotation.Repeatable;
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.peerat.backend.bonus.extract;
|
package be.jeffcheasey88.peeratcode.bonus.extract;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
|
@ -0,0 +1,49 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.bonus.extract;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.RequestType;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Router;
|
||||||
|
|
||||||
|
//A noter que le but est d'extraire des informations sans modifier le code source,
|
||||||
|
//comme les tests unitaire, ici je veux générer un élément textuel qui me donnera l'état des routes,
|
||||||
|
//je ne vais donc pas modifier la classe router pour donner un accès au route.
|
||||||
|
public class RouteExtracter {
|
||||||
|
|
||||||
|
private Router router;
|
||||||
|
|
||||||
|
public RouteExtracter(Router router){
|
||||||
|
this.router = router;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void extract() throws Exception{
|
||||||
|
Field field = Router.class.getDeclaredField("responses");
|
||||||
|
field.setAccessible(true);
|
||||||
|
Map<RequestType, Map<Response, Route>> responses = (Map<RequestType, Map<Response, Route>>) field.get(this.router);
|
||||||
|
for(Entry<RequestType, Map<Response, Route>> types : responses.entrySet()){
|
||||||
|
for(Entry<Response, Route> routes : types.getValue().entrySet()){
|
||||||
|
System.out.println("["+types.getKey()+"] ("+routes.getValue().needLogin()+") "+routes.getValue().path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void extractDoc() throws Exception{
|
||||||
|
Field field = Router.class.getDeclaredField("responses");
|
||||||
|
field.setAccessible(true);
|
||||||
|
Map<RequestType, Map<Response, Route>> responses = (Map<RequestType, Map<Response, Route>>) field.get(this.router);
|
||||||
|
for(Map<Response, Route> route : responses.values()){
|
||||||
|
for(Response response : route.keySet()){
|
||||||
|
Method method = response.getClass().getDeclaredMethod("exec",
|
||||||
|
Response.class.getDeclaredMethods()[0].getParameterTypes());
|
||||||
|
for(RouteDoc doc : method.getDeclaredAnnotationsByType(RouteDoc.class)){
|
||||||
|
System.out.println(doc.path()+((doc.path().isEmpty() ? "":"\n"))+" ["+doc.responseCode()+"] "+doc.responseDescription());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
src/be/jeffcheasey88/peeratcode/framework/Client.java
Normal file
60
src/be/jeffcheasey88/peeratcode/framework/Client.java
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.framework;
|
||||||
|
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.jose4j.jwa.AlgorithmConstraints.ConstraintType;
|
||||||
|
import org.jose4j.jws.AlgorithmIdentifiers;
|
||||||
|
import org.jose4j.jwt.JwtClaims;
|
||||||
|
import org.jose4j.jwt.consumer.JwtConsumer;
|
||||||
|
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
|
||||||
|
|
||||||
|
public class Client extends Thread{
|
||||||
|
|
||||||
|
private HttpReader reader;
|
||||||
|
private HttpWriter writer;
|
||||||
|
private Router router;
|
||||||
|
|
||||||
|
public Client(Socket socket, Router router) throws Exception{
|
||||||
|
this.reader = new HttpReader(socket);
|
||||||
|
this.writer = new HttpWriter(socket);
|
||||||
|
this.router = router;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(){
|
||||||
|
try{
|
||||||
|
String[] headers = reader.readLine().split("\\s");
|
||||||
|
System.out.println(Arrays.toString(headers));
|
||||||
|
reader.readHeaders();
|
||||||
|
|
||||||
|
router.exec(RequestType.valueOf(headers[0]), headers[1], isLogin(reader), reader, writer);
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
}catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private User isLogin(HttpReader reader) throws Exception{
|
||||||
|
String auth = reader.getHeader("Authorization");
|
||||||
|
if(auth == null) return null;
|
||||||
|
auth = auth.substring(7);
|
||||||
|
try{
|
||||||
|
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
|
||||||
|
.setRequireExpirationTime()
|
||||||
|
.setAllowedClockSkewInSeconds(30)
|
||||||
|
.setExpectedIssuer(this.router.getTokenIssuer())
|
||||||
|
.setVerificationKey(this.router.getWebKey().getKey())
|
||||||
|
.setJwsAlgorithmConstraints(ConstraintType.PERMIT, AlgorithmIdentifiers.RSA_USING_SHA256).build();
|
||||||
|
|
||||||
|
JwtClaims jwtClaims = jwtConsumer.processToClaims(auth);
|
||||||
|
return new User(jwtClaims);
|
||||||
|
}catch(Exception e){
|
||||||
|
writer.response(401, "Access-Control-Allow-Origin: *");
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
138
src/be/jeffcheasey88/peeratcode/framework/HttpReader.java
Normal file
138
src/be/jeffcheasey88/peeratcode/framework/HttpReader.java
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.framework;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.json.simple.parser.JSONParser;
|
||||||
|
|
||||||
|
public class HttpReader{
|
||||||
|
|
||||||
|
private static Pattern HEADER_PATTERN = Pattern.compile("^([^:]*):\\s+(.*)$");
|
||||||
|
|
||||||
|
private Socket socket;
|
||||||
|
private InputStream in;
|
||||||
|
private BufferedReader reader;
|
||||||
|
|
||||||
|
private Map<String, String> headers;
|
||||||
|
|
||||||
|
public HttpReader(Socket socket) throws Exception{
|
||||||
|
this.socket = socket;
|
||||||
|
this.in = socket.getInputStream();
|
||||||
|
this.reader = new BufferedReader(new InputStreamReader(in));
|
||||||
|
this.headers = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpReader(HttpReader origin) throws Exception{
|
||||||
|
this.socket = origin.socket;
|
||||||
|
this.in = origin.in;
|
||||||
|
this.reader = origin.reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isClosed(){
|
||||||
|
return this.socket.isClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readHeaders() throws Exception{
|
||||||
|
String line;
|
||||||
|
while(((line = reader.readLine()) != null) && (line.length() > 0)){
|
||||||
|
Matcher matcher = HEADER_PATTERN.matcher(line);
|
||||||
|
matcher.matches();
|
||||||
|
this.headers.put(matcher.group(1).toLowerCase(), matcher.group(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHeader(String key){
|
||||||
|
return this.headers.get(key.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read(byte[] buffer) throws IOException{
|
||||||
|
return this.in.read(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read(char[] buffer) throws IOException{
|
||||||
|
return this.reader.read(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String readLine() throws IOException{
|
||||||
|
return this.reader.readLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean ready() throws IOException{
|
||||||
|
return this.reader.ready();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readInt() throws Exception{
|
||||||
|
int result = 0;
|
||||||
|
result += this.in.read() << 24;
|
||||||
|
result += this.in.read() << 16;
|
||||||
|
result += this.in.read() << 8;
|
||||||
|
result += this.in.read();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T readJson() throws Exception{
|
||||||
|
String line = "";
|
||||||
|
while (ready()){
|
||||||
|
char[] c = new char[1];
|
||||||
|
read(c);
|
||||||
|
line += c[0];
|
||||||
|
if (c[0] == '}'){
|
||||||
|
Object parse;
|
||||||
|
try {
|
||||||
|
parse = new JSONParser().parse(line);
|
||||||
|
if (parse != null)
|
||||||
|
return (T) parse;
|
||||||
|
}catch(Exception e){}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
------WebKitFormBoundaryNUjiLBAMuX2dhxU7
|
||||||
|
Content-Disposition: form-data; name="answer"
|
||||||
|
|
||||||
|
12
|
||||||
|
------WebKitFormBoundaryNUjiLBAMuX2dhxU7
|
||||||
|
Content-Disposition: form-data; name="filename"
|
||||||
|
|
||||||
|
webpack.js
|
||||||
|
------WebKitFormBoundaryNUjiLBAMuX2dhxU7
|
||||||
|
Content-Disposition: form-data; name="code_file"; filename="webpack.js"
|
||||||
|
Content-Type: text/javascript
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryNUjiLBAMuX2dhxU7--
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public List<String> readMultiPartData() throws Exception{
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
String boundary = getHeader("content-type");
|
||||||
|
if(boundary == null) return list;
|
||||||
|
boundary = boundary.split(";")[1].split("=")[1];
|
||||||
|
readLine();
|
||||||
|
|
||||||
|
while(ready()){
|
||||||
|
String line;
|
||||||
|
while (((line = readLine()) != null) && (line.length() > 0));
|
||||||
|
String buffer = "";
|
||||||
|
while (((line = readLine()) != null) && (!line.startsWith("--"+boundary))){
|
||||||
|
buffer += line;
|
||||||
|
}
|
||||||
|
list.add(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
103
src/be/jeffcheasey88/peeratcode/framework/HttpWriter.java
Normal file
103
src/be/jeffcheasey88/peeratcode/framework/HttpWriter.java
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.framework;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class HttpWriter{
|
||||||
|
|
||||||
|
private OutputStream out;
|
||||||
|
private BufferedWriter writer;
|
||||||
|
|
||||||
|
public HttpWriter(Socket socket) throws Exception{
|
||||||
|
this.out = socket.getOutputStream();
|
||||||
|
this.writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpWriter(HttpWriter origin) throws Exception{
|
||||||
|
this.out = origin.out;
|
||||||
|
this.writer = origin.writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(byte[] buffer) throws IOException{
|
||||||
|
this.out.write(buffer);
|
||||||
|
this.out.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(String message) throws IOException{
|
||||||
|
this.writer.write(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush() throws IOException{
|
||||||
|
this.writer.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException{
|
||||||
|
this.writer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void response(int code, String... headers) throws Exception{
|
||||||
|
write("HTTP/1.1 "+code+codeMessage(code)+"\n");
|
||||||
|
for(String header : headers) write(header+"\n");
|
||||||
|
write("\n");
|
||||||
|
flush();
|
||||||
|
StackTraceElement[] e = Thread.currentThread().getStackTrace();
|
||||||
|
System.out.println(e[2]+" -> response "+code);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String[] HEIGHTBITS = new String[7];
|
||||||
|
private static String[] NINEBITS = new String[206];
|
||||||
|
|
||||||
|
static {
|
||||||
|
HEIGHTBITS[0] = " OK";
|
||||||
|
HEIGHTBITS[1] = " Created";
|
||||||
|
HEIGHTBITS[2] = " Accepted";
|
||||||
|
HEIGHTBITS[3] = " Non-Authoritative Information";
|
||||||
|
HEIGHTBITS[4] = " No Content";
|
||||||
|
HEIGHTBITS[5] = " Reset Content";
|
||||||
|
HEIGHTBITS[6] = " Partial Content";
|
||||||
|
|
||||||
|
NINEBITS[0] = " Multiple Choices";
|
||||||
|
NINEBITS[1] = " Moved Permanently";
|
||||||
|
NINEBITS[2] = " Temporary Redirect";
|
||||||
|
NINEBITS[3] = " See Other";
|
||||||
|
NINEBITS[4] = " Not Modified";
|
||||||
|
NINEBITS[5] = " Use Proxy";
|
||||||
|
|
||||||
|
NINEBITS[100] = " Bad Request";
|
||||||
|
NINEBITS[101] = " Unauthorized";
|
||||||
|
NINEBITS[102] = " Payment Required";
|
||||||
|
NINEBITS[103] = " Forbidden";
|
||||||
|
NINEBITS[104] = " Not Found";
|
||||||
|
NINEBITS[105] = " Method Not Allowed";
|
||||||
|
NINEBITS[106] = " Not Acceptable";
|
||||||
|
NINEBITS[107] = " Proxy Authentication Required";
|
||||||
|
NINEBITS[108] = " Request Time-Out";
|
||||||
|
NINEBITS[109] = " Conflict";
|
||||||
|
NINEBITS[110] = " Gone";
|
||||||
|
NINEBITS[111] = " Length Required";
|
||||||
|
NINEBITS[112] = " Precondition Failed";
|
||||||
|
NINEBITS[113] = " Request Entity Too Large";
|
||||||
|
NINEBITS[114] = " Request-URI Too Large";
|
||||||
|
NINEBITS[115] = " Unsupported Media Type";
|
||||||
|
NINEBITS[123] = " Locked";
|
||||||
|
NINEBITS[125] = " Too Early";
|
||||||
|
|
||||||
|
NINEBITS[200] = " Internal Server Error";
|
||||||
|
NINEBITS[201] = " Not Implemented";
|
||||||
|
NINEBITS[202] = " Bad Gateway";
|
||||||
|
NINEBITS[203] = " Service Unavailable";
|
||||||
|
NINEBITS[204] = " Gateway Timeout";
|
||||||
|
NINEBITS[205] = " HTTP Version Not Supported";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String codeMessage(int code){
|
||||||
|
if(code == 100) return " Continue";
|
||||||
|
if(code >> 8 == 0) return HEIGHTBITS[code-200];
|
||||||
|
return NINEBITS[code-300];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
59
src/be/jeffcheasey88/peeratcode/framework/Locker.java
Normal file
59
src/be/jeffcheasey88/peeratcode/framework/Locker.java
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.framework;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
public class Locker<V>{
|
||||||
|
|
||||||
|
private Map<Key, BlockingQueue<V>> map;
|
||||||
|
|
||||||
|
public Locker(){
|
||||||
|
this.map = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(Key key){
|
||||||
|
this.map.put(key, new LinkedBlockingQueue<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(Key key){
|
||||||
|
this.map.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlockingQueue<V> get(Key key){
|
||||||
|
return this.map.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(V value){
|
||||||
|
for(Entry<Key, BlockingQueue<V>> entry : this.map.entrySet()){
|
||||||
|
entry.getValue().add(value);
|
||||||
|
this.unlock(entry.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public V getValue(Key key){
|
||||||
|
BlockingQueue<V> queue = get(key);
|
||||||
|
if(queue.isEmpty()) return null;
|
||||||
|
return queue.poll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void lock(Key key) throws InterruptedException{
|
||||||
|
BlockingQueue<V> queue = get(key);
|
||||||
|
if(queue.isEmpty()){
|
||||||
|
synchronized(queue){
|
||||||
|
queue.wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unlock(Key key){
|
||||||
|
BlockingQueue<V> queue = get(key);
|
||||||
|
synchronized(queue){
|
||||||
|
queue.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Key{ public Key(){} }
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.framework;
|
||||||
|
|
||||||
|
public enum RequestType{
|
||||||
|
|
||||||
|
GET, POST, OPTIONS;
|
||||||
|
|
||||||
|
}
|
9
src/be/jeffcheasey88/peeratcode/framework/Response.java
Normal file
9
src/be/jeffcheasey88/peeratcode/framework/Response.java
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.framework;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
public interface Response{
|
||||||
|
|
||||||
|
void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception;
|
||||||
|
|
||||||
|
}
|
19
src/be/jeffcheasey88/peeratcode/framework/Route.java
Normal file
19
src/be/jeffcheasey88/peeratcode/framework/Route.java
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.framework;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface Route{
|
||||||
|
|
||||||
|
String path() default "^.*$";
|
||||||
|
|
||||||
|
RequestType type() default RequestType.GET;
|
||||||
|
|
||||||
|
boolean needLogin() default false;
|
||||||
|
|
||||||
|
boolean websocket() default false;
|
||||||
|
}
|
178
src/be/jeffcheasey88/peeratcode/framework/Router.java
Normal file
178
src/be/jeffcheasey88/peeratcode/framework/Router.java
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.framework;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.jose4j.jwk.RsaJsonWebKey;
|
||||||
|
import org.jose4j.jwk.RsaJwkGenerator;
|
||||||
|
import org.jose4j.jws.AlgorithmIdentifiers;
|
||||||
|
import org.jose4j.jws.JsonWebSignature;
|
||||||
|
import org.jose4j.jwt.JwtClaims;
|
||||||
|
import org.jose4j.lang.JoseException;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class Router{
|
||||||
|
|
||||||
|
private Map<RequestType, Map<Response, Route>> responses;
|
||||||
|
private Map<Response, Pattern> patterns;
|
||||||
|
private Response noFileFound;
|
||||||
|
private RsaJsonWebKey rsaJsonWebKey;
|
||||||
|
private DatabaseRepository repo;
|
||||||
|
private String token_issuer;
|
||||||
|
private int token_expiration;
|
||||||
|
|
||||||
|
public Router(DatabaseRepository repo, String token_issuer, int token_expiration) throws Exception{
|
||||||
|
this.repo = repo;
|
||||||
|
this.token_issuer = token_issuer;
|
||||||
|
this.token_expiration = token_expiration;
|
||||||
|
this.responses = new HashMap<>();
|
||||||
|
for(RequestType type : RequestType.values()) this.responses.put(type, new HashMap<>());
|
||||||
|
this.patterns = new HashMap<>();
|
||||||
|
this.rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseRepository getDataBase(){
|
||||||
|
return this.repo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register(Response response){
|
||||||
|
try{
|
||||||
|
Method method = response.getClass().getDeclaredMethod("exec",
|
||||||
|
Response.class.getDeclaredMethods()[0].getParameterTypes());
|
||||||
|
Route route = method.getAnnotation(Route.class);
|
||||||
|
|
||||||
|
this.responses.get(route.type()).put(response, route);
|
||||||
|
this.patterns.put(response, Pattern.compile(route.path()));
|
||||||
|
}catch(Exception e){
|
||||||
|
throw new IllegalArgumentException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefault(Response response){
|
||||||
|
this.noFileFound = response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void exec(RequestType type, String path, User user, HttpReader reader, HttpWriter writer) throws Exception{
|
||||||
|
if(type == null) return;
|
||||||
|
for(Entry<Response, Route> routes : this.responses.get(type).entrySet()){
|
||||||
|
Matcher matcher = this.patterns.get(routes.getKey()).matcher(path);
|
||||||
|
if(matcher.matches()){
|
||||||
|
if(user == null && routes.getValue().needLogin()){
|
||||||
|
writer.response(401, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(routes.getValue().websocket()){
|
||||||
|
switchToWebSocket(reader, writer);
|
||||||
|
reader = new WebSocketReader(reader);
|
||||||
|
writer = new WebSocketWriter(writer);
|
||||||
|
}
|
||||||
|
routes.getKey().exec(matcher, user, reader, writer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(noFileFound != null) noFileFound.exec(null, user, reader, writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RsaJsonWebKey getWebKey(){
|
||||||
|
return this.rsaJsonWebKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTokenIssuer(){
|
||||||
|
return this.token_issuer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String createAuthUser(int id) throws JoseException{
|
||||||
|
JwtClaims claims = new JwtClaims();
|
||||||
|
claims.setIssuer(token_issuer); // who creates the token and signs it
|
||||||
|
claims.setExpirationTimeMinutesInTheFuture(token_expiration);
|
||||||
|
claims.setGeneratedJwtId(); // a unique identifier for the token
|
||||||
|
claims.setIssuedAtToNow(); // when the token was issued/created (now)
|
||||||
|
claims.setNotBeforeMinutesInThePast(2); // time before which the token is not yet valid (2 minutes ago)
|
||||||
|
|
||||||
|
claims.setClaim("id", id);
|
||||||
|
|
||||||
|
JsonWebSignature jws = new JsonWebSignature();
|
||||||
|
jws.setPayload(claims.toJson());
|
||||||
|
jws.setKey(rsaJsonWebKey.getPrivateKey());
|
||||||
|
jws.setKeyIdHeaderValue(rsaJsonWebKey.getKeyId());
|
||||||
|
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
|
||||||
|
return jws.getCompactSerialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void switchToWebSocket(HttpReader reader, HttpWriter writer) throws Exception{
|
||||||
|
String key = reader.getHeader("Sec-WebSocket-Key");
|
||||||
|
if (key == null) throw new IllegalArgumentException();
|
||||||
|
|
||||||
|
writer.write("HTTP/1.1 101 Switching Protocols\n");
|
||||||
|
writer.write("Connection: Upgrade\n");
|
||||||
|
writer.write("Upgrade: websocket\n");
|
||||||
|
writer.write("Sec-WebSocket-Accept: " + printBase64Binary(MessageDigest.getInstance("SHA-1")
|
||||||
|
.digest((key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").getBytes("UTF-8"))) + "\n");
|
||||||
|
writer.write("\n");
|
||||||
|
writer.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// From javax.xml.bind.DatatypeConverter
|
||||||
|
private String printBase64Binary(byte[] array){
|
||||||
|
char[] arrayOfChar = new char[(array.length + 2) / 3 * 4];
|
||||||
|
int i = _printBase64Binary(array, 0, array.length, arrayOfChar, 0);
|
||||||
|
assert i == arrayOfChar.length;
|
||||||
|
return new String(arrayOfChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int _printBase64Binary(byte[] paramArrayOfbyte, int paramInt1, int paramInt2,
|
||||||
|
char[] paramArrayOfchar, int paramInt3){
|
||||||
|
int i = paramInt2;
|
||||||
|
int j;
|
||||||
|
for (j = paramInt1; i >= 3; j += 3){
|
||||||
|
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j] >> 2);
|
||||||
|
paramArrayOfchar[paramInt3++] = encode(
|
||||||
|
(paramArrayOfbyte[j] & 0x3) << 4 | paramArrayOfbyte[j + 1] >> 4 & 0xF);
|
||||||
|
paramArrayOfchar[paramInt3++] = encode(
|
||||||
|
(paramArrayOfbyte[j + 1] & 0xF) << 2 | paramArrayOfbyte[j + 2] >> 6 & 0x3);
|
||||||
|
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j + 2] & 0x3F);
|
||||||
|
i -= 3;
|
||||||
|
}
|
||||||
|
if (i == 1){
|
||||||
|
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j] >> 2);
|
||||||
|
paramArrayOfchar[paramInt3++] = encode((paramArrayOfbyte[j] & 0x3) << 4);
|
||||||
|
paramArrayOfchar[paramInt3++] = '=';
|
||||||
|
paramArrayOfchar[paramInt3++] = '=';
|
||||||
|
}
|
||||||
|
if (i == 2){
|
||||||
|
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j] >> 2);
|
||||||
|
paramArrayOfchar[paramInt3++] = encode(
|
||||||
|
(paramArrayOfbyte[j] & 0x3) << 4 | paramArrayOfbyte[j + 1] >> 4 & 0xF);
|
||||||
|
paramArrayOfchar[paramInt3++] = encode((paramArrayOfbyte[j + 1] & 0xF) << 2);
|
||||||
|
paramArrayOfchar[paramInt3++] = '=';
|
||||||
|
}
|
||||||
|
return paramInt3;
|
||||||
|
}
|
||||||
|
|
||||||
|
private char encode(int paramInt){
|
||||||
|
return encodeMap[paramInt & 0x3F];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final char[] encodeMap = initEncodeMap();
|
||||||
|
|
||||||
|
private static char[] initEncodeMap(){
|
||||||
|
char[] arrayOfChar = new char[64];
|
||||||
|
byte b;
|
||||||
|
for (b = 0; b < 26; b++)
|
||||||
|
arrayOfChar[b] = (char) (65 + b);
|
||||||
|
for (b = 26; b < 52; b++)
|
||||||
|
arrayOfChar[b] = (char) (97 + b - 26);
|
||||||
|
for (b = 52; b < 62; b++)
|
||||||
|
arrayOfChar[b] = (char) (48 + b - 52);
|
||||||
|
arrayOfChar[62] = '+';
|
||||||
|
arrayOfChar[63] = '/';
|
||||||
|
return arrayOfChar;
|
||||||
|
}
|
||||||
|
}
|
27
src/be/jeffcheasey88/peeratcode/framework/User.java
Normal file
27
src/be/jeffcheasey88/peeratcode/framework/User.java
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.framework;
|
||||||
|
|
||||||
|
import org.jose4j.jwt.JwtClaims;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Locker.Key;
|
||||||
|
|
||||||
|
public class User{
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private Key key;
|
||||||
|
|
||||||
|
public User(JwtClaims jwtClaims){
|
||||||
|
this.id = ((Long) jwtClaims.getClaimValue("id")).intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(Key key){
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Key getKey(){
|
||||||
|
return this.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId(){
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.framework;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class WebSocketReader extends HttpReader{
|
||||||
|
|
||||||
|
public WebSocketReader(HttpReader origin) throws Exception{
|
||||||
|
super(origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String readLine() throws IOException{
|
||||||
|
//read websocket found on StackOverFlow
|
||||||
|
int buffLenth = 1024;
|
||||||
|
int len = 0;
|
||||||
|
byte[] b = new byte[buffLenth];
|
||||||
|
// rawIn is a Socket.getInputStream();
|
||||||
|
while (true){
|
||||||
|
len = read(b);
|
||||||
|
if (len != -1){
|
||||||
|
byte rLength = 0;
|
||||||
|
int rMaskIndex = 2;
|
||||||
|
int rDataStart = 0;
|
||||||
|
// b[0] is always text in my case so no need to check;
|
||||||
|
byte data = b[1];
|
||||||
|
byte op = (byte) 127;
|
||||||
|
rLength = (byte) (data & op);
|
||||||
|
|
||||||
|
if (rLength == (byte) 126)
|
||||||
|
rMaskIndex = 4;
|
||||||
|
if (rLength == (byte) 127)
|
||||||
|
rMaskIndex = 10;
|
||||||
|
|
||||||
|
byte[] masks = new byte[4];
|
||||||
|
|
||||||
|
int j = 0;
|
||||||
|
int i = 0;
|
||||||
|
for (i = rMaskIndex; i < (rMaskIndex + 4); i++){
|
||||||
|
masks[j] = b[i];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
rDataStart = rMaskIndex + 4;
|
||||||
|
|
||||||
|
int messLen = len - rDataStart;
|
||||||
|
|
||||||
|
byte[] message = new byte[messLen];
|
||||||
|
|
||||||
|
for (i = rDataStart, j = 0; i < len; i++, j++){
|
||||||
|
message[j] = (byte) (b[i] ^ masks[j % 4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new String(message);
|
||||||
|
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.framework;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class WebSocketWriter extends HttpWriter{
|
||||||
|
|
||||||
|
public WebSocketWriter(HttpWriter origin) throws Exception{
|
||||||
|
super(origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(String message) throws IOException{
|
||||||
|
//write websocket found on StackOverFlow
|
||||||
|
byte[] rawData = message.getBytes();
|
||||||
|
|
||||||
|
int frameCount = 0;
|
||||||
|
byte[] frame = new byte[10];
|
||||||
|
|
||||||
|
frame[0] = (byte) 129;
|
||||||
|
|
||||||
|
if (rawData.length <= 125){
|
||||||
|
frame[1] = (byte) rawData.length;
|
||||||
|
frameCount = 2;
|
||||||
|
} else if (rawData.length >= 126 && rawData.length <= 65535){
|
||||||
|
frame[1] = (byte) 126;
|
||||||
|
int len = rawData.length;
|
||||||
|
frame[2] = (byte) ((len >> 8) & (byte) 255);
|
||||||
|
frame[3] = (byte) (len & (byte) 255);
|
||||||
|
frameCount = 4;
|
||||||
|
} else {
|
||||||
|
frame[1] = (byte) 127;
|
||||||
|
int len = rawData.length;
|
||||||
|
frame[2] = (byte) ((len >> 56) & (byte) 255);
|
||||||
|
frame[3] = (byte) ((len >> 48) & (byte) 255);
|
||||||
|
frame[4] = (byte) ((len >> 40) & (byte) 255);
|
||||||
|
frame[5] = (byte) ((len >> 32) & (byte) 255);
|
||||||
|
frame[6] = (byte) ((len >> 24) & (byte) 255);
|
||||||
|
frame[7] = (byte) ((len >> 16) & (byte) 255);
|
||||||
|
frame[8] = (byte) ((len >> 8) & (byte) 255);
|
||||||
|
frame[9] = (byte) (len & (byte) 255);
|
||||||
|
frameCount = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bLength = frameCount + rawData.length;
|
||||||
|
|
||||||
|
byte[] reply = new byte[bLength];
|
||||||
|
|
||||||
|
int bLim = 0;
|
||||||
|
for (int i = 0; i < frameCount; i++){
|
||||||
|
reply[bLim] = frame[i];
|
||||||
|
bLim++;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < rawData.length; i++){
|
||||||
|
reply[bLim] = rawData[i];
|
||||||
|
bLim++;
|
||||||
|
}
|
||||||
|
|
||||||
|
write(reply);
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,8 @@
|
||||||
package dev.peerat.backend.model;
|
package be.jeffcheasey88.peeratcode.model;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.mapping.Treasure;
|
||||||
|
|
||||||
|
@Treasure
|
||||||
public class Badge {
|
public class Badge {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
|
@ -1,7 +1,6 @@
|
||||||
package dev.peerat.backend.model;
|
package be.jeffcheasey88.peeratcode.model;
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class Chapter {
|
public class Chapter {
|
||||||
|
@ -35,13 +34,6 @@ public class Chapter {
|
||||||
this.puzzles = puzzles;
|
this.puzzles = puzzles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasStarted(){
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
boolean show = true;
|
|
||||||
if(startDate != null) show &= now.isAfter(startDate.toLocalDateTime());
|
|
||||||
return show;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Timestamp getStartDate() {
|
public Timestamp getStartDate() {
|
||||||
return startDate;
|
return startDate;
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.peerat.backend.model;
|
package be.jeffcheasey88.peeratcode.model;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ public class Completion{
|
||||||
private int score;
|
private int score;
|
||||||
private String puzzleName;
|
private String puzzleName;
|
||||||
|
|
||||||
public Completion(int playerId, int puzzleId, int tries, String fileName, int score){
|
public Completion(int playerId, int puzzleId, int tries, String fileName, int score) {
|
||||||
this(playerId, puzzleId, tries, score, fileName, null, null, null, null);
|
this(playerId, puzzleId, tries, score, fileName, null, null, null, null);
|
||||||
}
|
}
|
||||||
public Completion(int playerId, int puzzleId, int tries, String fileName, int score, String puzzleName) {
|
public Completion(int playerId, int puzzleId, int tries, String fileName, int score, String puzzleName) {
|
||||||
|
@ -22,13 +22,13 @@ public class Completion{
|
||||||
this(playerId, puzzleId, 0, 0, fileName, file, response, currentPuzzle, null);
|
this(playerId, puzzleId, 0, 0, fileName, file, response, currentPuzzle, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Completion(int initTries, int initScore){
|
public Completion(int initTries, int initScore) {
|
||||||
// For group leaderboard
|
// For group leaderboard
|
||||||
this(-1, -1, initTries, initScore, null, null, null, null, null);
|
this(-1, -1, initTries, initScore, null, null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Completion(int playerId, int puzzleId, int tries, int score, String fileName, byte[] file, byte[] response,
|
public Completion(int playerId, int puzzleId, int tries, int score, String fileName, byte[] file, byte[] response,
|
||||||
Puzzle currentPuzzle, String initPuzzleName){
|
Puzzle currentPuzzle, String initPuzzleName) {
|
||||||
this.playerId = playerId;
|
this.playerId = playerId;
|
||||||
this.puzzleId = puzzleId;
|
this.puzzleId = puzzleId;
|
||||||
this.fileName = fileName;
|
this.fileName = fileName;
|
||||||
|
@ -40,7 +40,7 @@ public class Completion{
|
||||||
this.score = score;
|
this.score = score;
|
||||||
|
|
||||||
if (currentPuzzle != null)
|
if (currentPuzzle != null)
|
||||||
addTry(currentPuzzle, response, 0);
|
addTry(currentPuzzle, response);
|
||||||
|
|
||||||
puzzleName = initPuzzleName;
|
puzzleName = initPuzzleName;
|
||||||
}
|
}
|
||||||
|
@ -62,17 +62,12 @@ public class Completion{
|
||||||
return tries;
|
return tries;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTry(Puzzle currentPuzzle, byte[] response, int chapter){
|
public void addTry(Puzzle currentPuzzle, byte[] response) {
|
||||||
if (score <= 0){
|
if (score <= 0){
|
||||||
tries++;
|
tries++;
|
||||||
if (response != null && Arrays.equals(currentPuzzle.getSoluce(), response)){
|
if (response != null && Arrays.equals(currentPuzzle.getSoluce(), response)) {
|
||||||
if (tries > 1) { // Loose 5% each try with a minimum of 1 for score
|
if (tries > 1) { // Loose 5% each try with a minimum of 1 for score
|
||||||
if(chapter < 4){
|
score = (int) Math.ceil(currentPuzzle.getScoreMax() * (1 - ((tries - 1) / 20.)));
|
||||||
score = currentPuzzle.getScoreMax();
|
|
||||||
}else{
|
|
||||||
score = (int) Math.ceil(currentPuzzle.getScoreMax() * (1 - ((tries - 1) / 20.)));
|
|
||||||
}
|
|
||||||
// score = currentPuzzle.getScoreMax();
|
|
||||||
if (score < 1)
|
if (score < 1)
|
||||||
score = 1;
|
score = 1;
|
||||||
} else
|
} else
|
|
@ -1,49 +1,35 @@
|
||||||
package dev.peerat.backend.model;
|
package be.jeffcheasey88.peeratcode.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.jose4j.json.internal.json_simple.JSONArray;
|
import org.json.simple.JSONArray;
|
||||||
import org.jose4j.json.internal.json_simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
import be.jeffcheasey88.peeratcode.mapping.SeaBottle;
|
|
||||||
import dev.peerat.framework.utils.json.JsonMap;
|
|
||||||
|
|
||||||
public class Group implements Comparable<Group> {
|
public class Group implements Comparable<Group> {
|
||||||
private String name;
|
private String name;
|
||||||
private Integer linkToChapter;
|
private Integer linkToChapter;
|
||||||
// private Integer linkToPuzzle;
|
// private Integer linkToPuzzle;
|
||||||
private List<Player> players;
|
private List<Player> players;
|
||||||
private int playerCount;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return "Group[name="+name+", chapter="+linkToChapter+"]";
|
return "Group[name="+name+", chapter="+linkToChapter+"]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Group(JsonMap json){
|
public Group(JSONObject json) {
|
||||||
this.name = (String) json.get("name");
|
this.name = (String) json.get("name");
|
||||||
if (json.has("chapter"))
|
if (json.containsKey("chapter"))
|
||||||
this.linkToChapter = ((Number) json.get("chapter")).intValue();
|
this.linkToChapter = ((Number) json.get("chapter")).intValue();
|
||||||
// if (json.has("puzzle"))
|
// if (json.containsKey("puzzle"))
|
||||||
// this.linkToPuzzle = ((Number) json.get("puzzle")).intValue();
|
// this.linkToPuzzle = ((Number) json.get("puzzle")).intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Group(String name, Integer initChap, Integer initPuzz, int playerCount) {
|
public Group(String name, Integer initChap, Integer initPuzz) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.linkToChapter = initChap;
|
this.linkToChapter = initChap;
|
||||||
// this.linkToPuzzle = initPuzz;
|
// this.linkToPuzzle = initPuzz;
|
||||||
this.playerCount = playerCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPlayerCount(){
|
|
||||||
return this.playerCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SeaBottle
|
|
||||||
public static Group getGroup(int player){
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addPlayer(Player newPlayer) {
|
public void addPlayer(Player newPlayer) {
|
||||||
|
@ -119,7 +105,6 @@ public class Group implements Comparable<Group> {
|
||||||
}
|
}
|
||||||
groupJSON.put("players", groupsPlayerJSON);
|
groupJSON.put("players", groupsPlayerJSON);
|
||||||
}
|
}
|
||||||
groupJSON.put("playerCount", this.playerCount);
|
|
||||||
return groupJSON;
|
return groupJSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +124,7 @@ public class Group implements Comparable<Group> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode(){
|
public int hashCode() {
|
||||||
return Objects.hash(name);
|
return Objects.hash(name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package dev.peerat.backend.model;
|
package be.jeffcheasey88.peeratcode.model;
|
||||||
|
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import dev.peerat.framework.utils.json.JsonArray;
|
import org.json.simple.JSONArray;
|
||||||
import dev.peerat.framework.utils.json.JsonMap;
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
public class Player implements Comparable<Player> {
|
public class Player implements Comparable<Player> {
|
||||||
private String pseudo;
|
private String pseudo;
|
||||||
|
@ -22,12 +22,12 @@ public class Player implements Comparable<Player> {
|
||||||
|
|
||||||
private Set<Badge> badges;
|
private Set<Badge> badges;
|
||||||
|
|
||||||
public Player(String pseudo, String email, String firstname, String lastname) {
|
public Player(String pseudo, String email, String firstname, String lastname, String description) {
|
||||||
this.pseudo = pseudo;
|
this.pseudo = pseudo;
|
||||||
this.email = email;
|
this.email = email;
|
||||||
this.firstname = firstname;
|
this.firstname = firstname;
|
||||||
this.lastname = lastname;
|
this.lastname = lastname;
|
||||||
this.description = "";
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player(String pseudo, int score, int tries) {
|
public Player(String pseudo, int score, int tries) {
|
||||||
|
@ -37,15 +37,6 @@ public class Player implements Comparable<Player> {
|
||||||
email = ""; // TO make compareTo and equals works as usual
|
email = ""; // TO make compareTo and equals works as usual
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player(String email) {
|
|
||||||
// For player find in Map during register process
|
|
||||||
this.email = email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPseudo(String pseudo){
|
|
||||||
this.pseudo = pseudo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPseudo() {
|
public String getPseudo() {
|
||||||
return this.pseudo;
|
return this.pseudo;
|
||||||
}
|
}
|
||||||
|
@ -70,9 +61,9 @@ public class Player implements Comparable<Player> {
|
||||||
return groups;
|
return groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonArray getJsonGroups() {
|
public JSONArray getJsonGroups() {
|
||||||
if (groups != null) {
|
if (groups != null) {
|
||||||
JsonArray groupsJSON = new JsonArray();
|
JSONArray groupsJSON = new JSONArray();
|
||||||
for (Group group : groups) {
|
for (Group group : groups) {
|
||||||
groupsJSON.add(group.toJson());
|
groupsJSON.add(group.toJson());
|
||||||
}
|
}
|
||||||
|
@ -121,13 +112,13 @@ public class Player implements Comparable<Player> {
|
||||||
return completions.size();
|
return completions.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonArray getJsonCompletions() {
|
public JSONArray getJsonCompletions() {
|
||||||
JsonArray completionsJSON = new JsonArray();
|
JSONArray completionsJSON = new JSONArray();
|
||||||
for (Completion completion : completions) {
|
for (Completion completion : completions) {
|
||||||
JsonMap completionJSON = new JsonMap();
|
JSONObject completionJSON = new JSONObject();
|
||||||
completionJSON.set("puzzleName", completion.getPuzzleName());
|
completionJSON.put("puzzleName", completion.getPuzzleName());
|
||||||
completionJSON.set("tries", completion.getTries());
|
completionJSON.put("tries", completion.getTries());
|
||||||
completionJSON.set("score", completion.getScore());
|
completionJSON.put("score", completion.getScore());
|
||||||
completionsJSON.add(completionJSON);
|
completionsJSON.add(completionJSON);
|
||||||
}
|
}
|
||||||
return completionsJSON;
|
return completionsJSON;
|
||||||
|
@ -145,17 +136,17 @@ public class Player implements Comparable<Player> {
|
||||||
return badges;
|
return badges;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonArray getJsonBadges() {
|
public JSONArray getJsonBadges() {
|
||||||
if (badges == null)
|
if (badges == null)
|
||||||
return null;
|
return null;
|
||||||
JsonArray badgesJSON = new JsonArray();
|
JSONArray badgesJSON = new JSONArray();
|
||||||
for (Badge badge : badges) {
|
for (Badge badge : badges) {
|
||||||
JsonMap badgeJSON = new JsonMap();
|
JSONObject badgeJSON = new JSONObject();
|
||||||
badgeJSON.set("name", badge.getName());
|
badgeJSON.put("name", badge.getName());
|
||||||
byte[] logo = badge.getLogo();
|
byte[] logo = badge.getLogo();
|
||||||
if (logo != null)
|
if (logo != null)
|
||||||
badgeJSON.set("logo", Base64.getEncoder().encodeToString(logo));
|
badgeJSON.put("logo", Base64.getEncoder().encodeToString(logo));
|
||||||
badgeJSON.set("level", badge.getLevel());
|
badgeJSON.put("level", badge.getLevel());
|
||||||
badgesJSON.add(badgeJSON);
|
badgesJSON.add(badgeJSON);
|
||||||
}
|
}
|
||||||
return badgesJSON;
|
return badgesJSON;
|
||||||
|
@ -189,7 +180,7 @@ public class Player implements Comparable<Player> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode(){
|
public int hashCode() {
|
||||||
return Objects.hash(email, pseudo);
|
return Objects.hash(email, pseudo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package dev.peerat.backend.model;
|
package be.jeffcheasey88.peeratcode.model;
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import dev.peerat.framework.utils.json.JsonArray;
|
import org.json.simple.JSONArray;
|
||||||
import dev.peerat.framework.utils.json.JsonMap;
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
public class Puzzle {
|
public class Puzzle {
|
||||||
|
|
||||||
|
@ -19,10 +17,9 @@ public class Puzzle {
|
||||||
private int scoreMax;
|
private int scoreMax;
|
||||||
private Set<String> tags;
|
private Set<String> tags;
|
||||||
private int depend;
|
private int depend;
|
||||||
private Timestamp startDate;
|
|
||||||
|
|
||||||
public Puzzle(int id, String name, String content, byte[] soluce, String verify, int scoreMax, String tags,
|
public Puzzle(int id, String name, String content, byte[] soluce, String verify, int scoreMax, String tags,
|
||||||
int depend, Timestamp startDate) {
|
int depend) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.content = content;
|
this.content = content;
|
||||||
|
@ -31,7 +28,6 @@ public class Puzzle {
|
||||||
this.scoreMax = scoreMax;
|
this.scoreMax = scoreMax;
|
||||||
setTags(tags);
|
setTags(tags);
|
||||||
this.depend = depend;
|
this.depend = depend;
|
||||||
this.startDate = startDate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
|
@ -63,13 +59,13 @@ public class Puzzle {
|
||||||
*
|
*
|
||||||
* @return DEATH
|
* @return DEATH
|
||||||
*/
|
*/
|
||||||
public JsonArray getJsonTags() {
|
public JSONArray getJsonTags() {
|
||||||
if (tags == null)
|
if (tags == null)
|
||||||
return null;
|
return null;
|
||||||
JsonArray tagsJSON = new JsonArray();
|
JSONArray tagsJSON = new JSONArray();
|
||||||
for (String tag : tags) {
|
for (String tag : tags) {
|
||||||
JsonMap tagJSON = new JsonMap();
|
JSONObject tagJSON = new JSONObject();
|
||||||
tagJSON.set("name", tag);
|
tagJSON.put("name", tag);
|
||||||
tagsJSON.add(tagJSON);
|
tagsJSON.add(tagJSON);
|
||||||
}
|
}
|
||||||
return tagsJSON;
|
return tagsJSON;
|
||||||
|
@ -86,13 +82,6 @@ public class Puzzle {
|
||||||
return this.depend;
|
return this.depend;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasStarted(){
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
boolean show = true;
|
|
||||||
if(startDate != null) show &= now.isAfter(startDate.toLocalDateTime());
|
|
||||||
return show;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object object) {
|
public boolean equals(Object object) {
|
||||||
if (this == object)
|
if (this == object)
|
53
src/be/jeffcheasey88/peeratcode/parser/java/Annotation.java
Normal file
53
src/be/jeffcheasey88/peeratcode/parser/java/Annotation.java
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class Annotation extends JavaElement{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*@\\s*([^\\s\\^]*)\\s*(\\^GENERIC_PARENTHESIS\\d+)?)");
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
private String param;
|
||||||
|
|
||||||
|
public Annotation(){}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception {
|
||||||
|
Matcher matcher = PATTERN.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
System.out.println("parseAnnotation("+content.length()+") "+content);
|
||||||
|
|
||||||
|
this.type = matcher.group(2);
|
||||||
|
this.param = matcher.group(3);
|
||||||
|
|
||||||
|
return matcher.group(1).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType(){
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception {
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="@"+type+(param == null ? "":param));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(Function<JavaElement, Boolean> search, Function<List<JavaElement>, Boolean> deep, List<JavaElement> trace) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(BiFunction<JavaElement, List<JavaElement>, Boolean> search, List<JavaElement> trace) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
28
src/be/jeffcheasey88/peeratcode/parser/java/ArrayBuffer.java
Normal file
28
src/be/jeffcheasey88/peeratcode/parser/java/ArrayBuffer.java
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
public class ArrayBuffer<E>{
|
||||||
|
|
||||||
|
private E[] elements;
|
||||||
|
|
||||||
|
public ArrayBuffer(java.lang.Class<?> type){
|
||||||
|
this.elements = (E[]) Array.newInstance(type, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(E e){
|
||||||
|
E[] copy = (E[]) Array.newInstance(e.getClass(), this.elements.length+1);
|
||||||
|
System.arraycopy(elements, 0, copy, 0, elements.length);
|
||||||
|
copy[elements.length] = e;
|
||||||
|
this.elements = copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void append(java.util.function.Function<E, E> modifier){
|
||||||
|
this.elements[elements.length-1] = modifier.apply(this.elements[elements.length-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<E> iterator(){
|
||||||
|
return new ArrayIterator<E>(elements);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
public class ArrayIterator<E> implements Iterator<E>{
|
||||||
|
|
||||||
|
private E[] elements;
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
public ArrayIterator(E[] elements){
|
||||||
|
E[] copy = (E[]) Array.newInstance(elements.getClass().getComponentType(), elements.length);
|
||||||
|
System.arraycopy(elements, 0, copy, 0, elements.length);
|
||||||
|
this.elements = copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext(){
|
||||||
|
return index < elements.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E next(){
|
||||||
|
return elements[index++];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
172
src/be/jeffcheasey88/peeratcode/parser/java/Class.java
Normal file
172
src/be/jeffcheasey88/peeratcode/parser/java/Class.java
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java;
|
||||||
|
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool.Cleaner;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.Variable.MultipleDeclaratedVariable;
|
||||||
|
|
||||||
|
public class Class extends JavaElement{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*([^\\{]*)\\{(.*)\\})\\s*$");
|
||||||
|
|
||||||
|
private List<Annotation> annotations;
|
||||||
|
|
||||||
|
private int modifier;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private List<JavaElement> childs;
|
||||||
|
|
||||||
|
public Class(){
|
||||||
|
this.annotations = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
Matcher matcher = PATTERN.matcher(content);
|
||||||
|
matcher.matches();
|
||||||
|
|
||||||
|
Iterator<String> values = new ArrayIterator<>(matcher.group(2).split("\\s+"));
|
||||||
|
String value = null;
|
||||||
|
int modifier;
|
||||||
|
while(values.hasNext() && ((value = values.next()).charAt(0) == '@')){
|
||||||
|
Annotation annotation = new Annotation();
|
||||||
|
annotation.parse(value, global, local);
|
||||||
|
this.annotations.add(annotation);
|
||||||
|
}
|
||||||
|
if((modifier = JavaParser.getModifier(value)) > 0){
|
||||||
|
do{
|
||||||
|
this.modifier+=modifier;
|
||||||
|
}while(values.hasNext() && (modifier = JavaParser.getModifier(value = values.next())) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
String type = value; //class interface enum
|
||||||
|
this.name = values.next();
|
||||||
|
|
||||||
|
if(values.hasNext()){
|
||||||
|
//extends implements
|
||||||
|
}
|
||||||
|
|
||||||
|
this.childs = new ArrayList<>();
|
||||||
|
|
||||||
|
CleanerPool tmp = new CleanerPool(new Cleaner("GENERIC_PARENTHESIS", '(', ')'));
|
||||||
|
|
||||||
|
content = matcher.group(3);
|
||||||
|
Pattern empty = Pattern.compile("^\\s*$");
|
||||||
|
while(!(empty.matcher(content).matches())){
|
||||||
|
String zip = tmp.clean(content);
|
||||||
|
int quotes = indexOf(zip,";");
|
||||||
|
int braces = indexOf(zip,"\\{");
|
||||||
|
int equals = indexOf(zip,"=");
|
||||||
|
if((quotes < braces && quotes < equals) || (equals < braces)){
|
||||||
|
Variable variable = new Variable();
|
||||||
|
int index = variable.parse(content, global, local);
|
||||||
|
content = content.substring(index);
|
||||||
|
boolean quote = content.startsWith(",");
|
||||||
|
if(quote){
|
||||||
|
content = content.substring(1);
|
||||||
|
|
||||||
|
MultipleDeclaratedVariable multiple = new MultipleDeclaratedVariable(variable.getModifier(), variable.getType());
|
||||||
|
multiple.addVariable(variable.getName(), variable.getValue());
|
||||||
|
while(quote){
|
||||||
|
variable = new Variable(variable.getModifier(), variable.getType());
|
||||||
|
index = variable.parse(content, global, local);
|
||||||
|
content = content.substring(index);
|
||||||
|
quote = content.startsWith(",");
|
||||||
|
if(quote) content = content.substring(1);
|
||||||
|
|
||||||
|
multiple.addVariable(variable.getName(), variable.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.childs.add(multiple);
|
||||||
|
}else{
|
||||||
|
this.childs.add(variable);
|
||||||
|
}
|
||||||
|
|
||||||
|
content = content.substring(1);
|
||||||
|
}else{
|
||||||
|
// System.out.println("Function "+content);
|
||||||
|
Function func = new Function();
|
||||||
|
int index = func.parse(content, global, local);
|
||||||
|
this.childs.add(func);
|
||||||
|
content = content.substring(index);
|
||||||
|
// System.out.println("End "+content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return cleaner.unzip(matcher.group(1), ((s,p) -> s)).length();
|
||||||
|
return matcher.group(1).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int indexOf(String value, String target){
|
||||||
|
return value.split(target)[0].length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getModifier(){
|
||||||
|
return this.modifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName(){
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JavaElement> getChilds(){
|
||||||
|
return this.childs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public List<Variable> getVariables(){
|
||||||
|
// return this.vars;
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
for(Annotation annotation : this.annotations){
|
||||||
|
annotation.build(buffer, tab);
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+=Modifier.toString(modifier)+" "+this.name+"{");
|
||||||
|
buffer.add("");
|
||||||
|
|
||||||
|
for(JavaElement child : this.childs){
|
||||||
|
child.build(buffer, tab+1);
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="}");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(java.util.function.Function<JavaElement, Boolean> search, java.util.function.Function<List<JavaElement>, Boolean> deep, List<JavaElement> trace){
|
||||||
|
if(search.apply(this)) return (E)this;
|
||||||
|
trace.add(this);
|
||||||
|
int index = trace.size()-1;
|
||||||
|
if(!deep.apply(trace)) return null;
|
||||||
|
for(JavaElement element : this.childs){
|
||||||
|
E result = element.find(search, deep, trace);
|
||||||
|
if(result != null) return result;
|
||||||
|
}
|
||||||
|
trace.remove(index);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(BiFunction<JavaElement, List<JavaElement>, Boolean> search, List<JavaElement> trace){
|
||||||
|
trace.add(this);
|
||||||
|
int index = trace.size()-1;
|
||||||
|
if(search.apply(this, trace)) return (E)this;
|
||||||
|
for(JavaElement element : this.childs){
|
||||||
|
E result = element.find(search, trace);
|
||||||
|
if(result != null) return result;
|
||||||
|
}
|
||||||
|
trace.remove(index);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
175
src/be/jeffcheasey88/peeratcode/parser/java/CleanerPool.java
Normal file
175
src/be/jeffcheasey88/peeratcode/parser/java/CleanerPool.java
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class CleanerPool{
|
||||||
|
|
||||||
|
private List<Cleaner> cleaners;
|
||||||
|
|
||||||
|
public CleanerPool(Cleaner... cleaners){
|
||||||
|
this.cleaners = new ArrayList<>(Arrays.asList(cleaners));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CleanerPool group(CleanerPool... pools){
|
||||||
|
CleanerPool pool = new CleanerPool();
|
||||||
|
pool.cleaners.addAll(cleaners);
|
||||||
|
for(CleanerPool other : pools){
|
||||||
|
for(Cleaner cleaner : other.cleaners){
|
||||||
|
boolean contains = false;
|
||||||
|
for(Cleaner include : pool.cleaners){
|
||||||
|
if(include.getPattern().equals(cleaner.getPattern())){
|
||||||
|
contains = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(contains) continue;
|
||||||
|
pool.cleaners.add(cleaner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(){
|
||||||
|
String s = "CleanerPool[\n";
|
||||||
|
for(Cleaner cleaner : cleaners) s+=cleaner.pattern+"['"+cleaner.open+"' -> '"+cleaner.close+"']\n";
|
||||||
|
s+="\n]";
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String clean(String value){
|
||||||
|
for(Cleaner cleaner : this.cleaners) value = cleaner.clean(value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String unzipOne(String value, BiFunction<String, String, String> modifier){
|
||||||
|
boolean edited;
|
||||||
|
String tmp = value;
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
do{
|
||||||
|
edited = false;
|
||||||
|
for(Cleaner cleaner : this.cleaners){
|
||||||
|
Matcher matcher = cleaner.getMatcher(tmp);
|
||||||
|
if(matcher.matches()){
|
||||||
|
String key = matcher.group(2);
|
||||||
|
String zip = cleaner.getConstant(key);
|
||||||
|
String modified = modifier.apply(zip, cleaner.getPattern());
|
||||||
|
if(modified == null) continue;
|
||||||
|
map.put(key, cleaner.open+modified+cleaner.close);
|
||||||
|
tmp = matcher.group(1)+cleaner.open+modified+cleaner.close+matcher.group(3);
|
||||||
|
edited = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}while(edited);
|
||||||
|
|
||||||
|
String base = value;
|
||||||
|
for(Entry<String, String> unzip : map.entrySet()){
|
||||||
|
Pattern pattern = Pattern.compile("\\"+unzip.getKey()+"(?<e>([^\\d]|$))");
|
||||||
|
if(pattern.matcher(base).find()) value = pattern.matcher(value).replaceAll(unzip.getValue()+"${e}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String unzip(String value, BiFunction<String, String, String> modifier){
|
||||||
|
boolean edited;
|
||||||
|
do{
|
||||||
|
edited = false;
|
||||||
|
for(Cleaner cleaner : this.cleaners){
|
||||||
|
Matcher matcher = cleaner.getMatcher(value);
|
||||||
|
if(matcher.matches()){
|
||||||
|
String key = matcher.group(2);
|
||||||
|
String zip = cleaner.getConstant(key);
|
||||||
|
String modified = modifier.apply(zip, cleaner.getPattern());
|
||||||
|
if(modified == null) continue;
|
||||||
|
value = matcher.group(1)+cleaner.open+modified+cleaner.close+matcher.group(3);
|
||||||
|
edited = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}while(edited);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Cleaner{
|
||||||
|
|
||||||
|
private Pattern rPattern;
|
||||||
|
|
||||||
|
private String pattern;
|
||||||
|
private char open;
|
||||||
|
private char close;
|
||||||
|
|
||||||
|
public List<String> constants;
|
||||||
|
|
||||||
|
public Cleaner(String pattern, char open, char close){
|
||||||
|
this.pattern = "^"+pattern;
|
||||||
|
this.open = open;
|
||||||
|
this.close = close;
|
||||||
|
this.rPattern = Pattern.compile("^(.*)(\\^"+pattern+"\\d+)(.*)$");
|
||||||
|
this.constants = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Matcher getMatcher(String value){
|
||||||
|
return this.rPattern.matcher(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPattern(){
|
||||||
|
return this.pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConstant(String value){
|
||||||
|
return this.constants.get(Integer.parseInt(value.replace(this.pattern, "")));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String clean(String value){
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for(int i = 0; i < value.length(); i++){
|
||||||
|
char c = value.charAt(i);
|
||||||
|
if(c == open){
|
||||||
|
int cut = cutOpenable(value.substring(i+1), constants, pattern, open, close);
|
||||||
|
if(cut < 0){
|
||||||
|
builder.append(c);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
i+=cut;
|
||||||
|
builder.append(pattern+(constants.size()-1));
|
||||||
|
}else{
|
||||||
|
builder.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int cutOpenable(String value, List<String> constants, String pattern, char open, char close){
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
int i = 0;
|
||||||
|
for(;i < value.length(); i++){
|
||||||
|
char c = value.charAt(i);
|
||||||
|
if(c == close){
|
||||||
|
constants.add(builder.toString());
|
||||||
|
return i+1;
|
||||||
|
}else if(c == open){
|
||||||
|
int cut = cutOpenable(value.substring(i+1), constants, pattern, open, close);
|
||||||
|
if(cut < 0){
|
||||||
|
builder.append(c);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
i+=cut;
|
||||||
|
builder.append(pattern+(constants.size()-1));
|
||||||
|
}else{
|
||||||
|
builder.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
160
src/be/jeffcheasey88/peeratcode/parser/java/Function.java
Normal file
160
src/be/jeffcheasey88/peeratcode/parser/java/Function.java
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java;
|
||||||
|
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool.Cleaner;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.operations.OperationContainer;
|
||||||
|
|
||||||
|
public class Function extends OperationContainer{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*([^(]*)\\(([^)]*)\\)\\s*([^{]*)\\{)(.*)$");
|
||||||
|
private static Pattern ANNOTATION_PATTERN = Pattern.compile("^(\\s*(@\\s*[^\\s]+\\s*\\^GENERIC_PARENTHESIS\\d+\\s+))");
|
||||||
|
|
||||||
|
private List<Annotation> annotations;
|
||||||
|
private int modifier;
|
||||||
|
private String returnType;
|
||||||
|
private String name;
|
||||||
|
private List<Variable> parameters;
|
||||||
|
private String exceptions;
|
||||||
|
|
||||||
|
private boolean constructor;
|
||||||
|
|
||||||
|
public Function(){
|
||||||
|
this.annotations = new ArrayList<>();
|
||||||
|
this.parameters = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
local = new CleanerPool(new Cleaner("GENERIC_PARENTHESIS", '(', ')'));
|
||||||
|
content = local.clean(content);
|
||||||
|
|
||||||
|
int annotationOffset = 0;
|
||||||
|
|
||||||
|
Matcher matcher;
|
||||||
|
while((matcher = ANNOTATION_PATTERN.matcher(content)).lookingAt()){
|
||||||
|
String annot = matcher.group(1);
|
||||||
|
annotationOffset+=local.unzip(annot, (s,p) -> s).length();
|
||||||
|
content = content.substring(annot.length());
|
||||||
|
Annotation annotation = new Annotation();
|
||||||
|
annotation.parse(matcher.group(2), global, local);
|
||||||
|
this.annotations.add(annotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
content = local.unzipOne(local.clean(content), (s,p) -> s);
|
||||||
|
matcher = PATTERN.matcher(content);
|
||||||
|
matcher.matches();
|
||||||
|
|
||||||
|
attribute(matcher.group(2));
|
||||||
|
parameters(matcher.group(3)+";", global, local);
|
||||||
|
this.exceptions = matcher.group(4).trim();
|
||||||
|
|
||||||
|
local = local.group(new CleanerPool(new Cleaner("GENERIC_FUNCTION", '{', '}')));
|
||||||
|
|
||||||
|
|
||||||
|
String zip = local.clean("{"+matcher.group(5));
|
||||||
|
String body = local.unzipOne(zip, (s,p) -> s);
|
||||||
|
String unzip = body.substring(1, body.indexOf('}'));
|
||||||
|
|
||||||
|
super.parse(local.clean(unzip), global, local);
|
||||||
|
|
||||||
|
return annotationOffset+local.unzip(matcher.group(1), (s,p) -> s).length()+local.unzip(unzip, ((s,p) -> s)).length()+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Pattern UNZIP_STICK = Pattern.compile("\\s+(?<e>[<|(|\\[|\"|'])");
|
||||||
|
private static Pattern UNZIP_MAJ = Pattern.compile(">(?<e>[^>\\d,;(])");
|
||||||
|
private static Pattern UNZIP_ARRAY = Pattern.compile("](?<e>[^\\[\\d,;])");
|
||||||
|
|
||||||
|
private void attribute(String content) throws Exception{
|
||||||
|
CleanerPool generic = new CleanerPool(
|
||||||
|
new Cleaner("GENERIC_TYPE_",'<','>'),
|
||||||
|
new Cleaner("GENERIC_ARRAY",'[',']'));
|
||||||
|
String zip = generic.clean(content);
|
||||||
|
String unzip = generic.unzip(zip, (value, pattern) -> {
|
||||||
|
return value.replaceAll("\\s+", "");
|
||||||
|
});
|
||||||
|
|
||||||
|
unzip = UNZIP_STICK.matcher(unzip).replaceAll("${e}");
|
||||||
|
unzip = UNZIP_MAJ.matcher(unzip).replaceAll("> ${e}");
|
||||||
|
unzip = UNZIP_ARRAY.matcher(unzip).replaceAll("] ${e}");
|
||||||
|
|
||||||
|
System.out.println("split space on "+unzip);
|
||||||
|
|
||||||
|
Iterator<String> values = new ArrayIterator<>(unzip.split("\\s+"));
|
||||||
|
String value = null;
|
||||||
|
int modifier;
|
||||||
|
while(values.hasNext() && ((value = values.next()).charAt(0) == '@')){
|
||||||
|
Annotation annotation = new Annotation();
|
||||||
|
annotation.parse(value, null, generic);
|
||||||
|
this.annotations.add(annotation);
|
||||||
|
System.out.println("parse annotation "+value);
|
||||||
|
}
|
||||||
|
System.out.println("out in("+values.hasNext()+" -> "+value.charAt(0)+") "+value);
|
||||||
|
if((modifier = JavaParser.getModifier(value)) > 0){
|
||||||
|
do{
|
||||||
|
this.modifier+=modifier;
|
||||||
|
}while(values.hasNext() && (modifier = JavaParser.getModifier(value = values.next())) > 0);
|
||||||
|
}
|
||||||
|
if(this.returnType == null){
|
||||||
|
this.returnType = value;
|
||||||
|
if(values.hasNext()) value = values.next();
|
||||||
|
else constructor = true;
|
||||||
|
}
|
||||||
|
if(this.name == null){
|
||||||
|
this.name = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parameters(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
if(content.length() == 1) return;
|
||||||
|
boolean quote = false;
|
||||||
|
do {
|
||||||
|
Variable variable = new Variable();
|
||||||
|
int index = variable.parse(content, global, local);
|
||||||
|
this.parameters.add(variable);
|
||||||
|
content = content.substring(index);
|
||||||
|
quote = content.startsWith(",");
|
||||||
|
if(quote) content = content.substring(1);
|
||||||
|
}while(quote);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
for(Annotation annotation : this.annotations){
|
||||||
|
annotation.build(buffer, tab);
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean empty = getChilds().size() == 0;
|
||||||
|
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+=Modifier.toString(modifier)+" "+(constructor ? "" : returnType+" ")+name+"(");
|
||||||
|
boolean first = true;
|
||||||
|
for(Variable variable : this.parameters){
|
||||||
|
for(Annotation annotation : variable.getAnnotations()){
|
||||||
|
annotation.build(buffer, 0);
|
||||||
|
buffer.append((s) -> s+=" ");
|
||||||
|
}
|
||||||
|
if(first) first = false;
|
||||||
|
else{
|
||||||
|
buffer.append((s) -> s+=",");
|
||||||
|
}
|
||||||
|
buffer.append((s) -> s+=variable.getType()+" "+variable.getName());
|
||||||
|
}
|
||||||
|
buffer.append((s) -> s+=") "+exceptions+"{"+((empty ? "}":"")));
|
||||||
|
buffer.add("");
|
||||||
|
|
||||||
|
if(empty) return;
|
||||||
|
|
||||||
|
for(JavaElement child : getChilds()) child.build(buffer, tab+1);
|
||||||
|
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="}");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
30
src/be/jeffcheasey88/peeratcode/parser/java/Import.java
Normal file
30
src/be/jeffcheasey88/peeratcode/parser/java/Import.java
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class Import {
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*import\\s+([^;]*);)");
|
||||||
|
|
||||||
|
public static boolean isImport(String content){
|
||||||
|
return PATTERN.matcher(content).lookingAt();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Import(){}
|
||||||
|
|
||||||
|
public int parse(String content) throws Exception{
|
||||||
|
Matcher matcher = PATTERN.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
this.name = matcher.group(2);
|
||||||
|
return matcher.group(1).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
// public int doYouSeeMe(){ return false; }
|
||||||
|
|
||||||
|
public String getName(){
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
}
|
20
src/be/jeffcheasey88/peeratcode/parser/java/JavaElement.java
Normal file
20
src/be/jeffcheasey88/peeratcode/parser/java/JavaElement.java
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public abstract class JavaElement {
|
||||||
|
|
||||||
|
public abstract int parse(String content, CleanerPool global, CleanerPool local) throws Exception;
|
||||||
|
|
||||||
|
public abstract <E extends JavaElement> E find(Function<JavaElement, Boolean> search, Function<List<JavaElement>, Boolean> deep, List<JavaElement> trace);
|
||||||
|
public abstract <E extends JavaElement> E find(BiFunction<JavaElement, List<JavaElement>, Boolean> search, List<JavaElement> trace);
|
||||||
|
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception {
|
||||||
|
String spacement = "";
|
||||||
|
for(int i = 0; i < tab; i++) spacement+="\t";
|
||||||
|
final String modifier = spacement;
|
||||||
|
buffer.append((s) -> s+=modifier);
|
||||||
|
}
|
||||||
|
}
|
179
src/be/jeffcheasey88/peeratcode/parser/java/JavaParser.java
Normal file
179
src/be/jeffcheasey88/peeratcode/parser/java/JavaParser.java
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool.Cleaner;
|
||||||
|
|
||||||
|
public class JavaParser{
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
File file = new File("C:\\Users\\jeffc\\eclipse-workspace\\peer-at-code-backend\\src\\be\\jeffcheasey88\\peeratcode\\routes\\PuzzleResponse.java");
|
||||||
|
BufferedReader reader = new BufferedReader(new FileReader(file));
|
||||||
|
|
||||||
|
JavaParser parser = new JavaParser();
|
||||||
|
parser.parse(reader);
|
||||||
|
System.out.println("build-----------------");
|
||||||
|
parser.build(new BufferedWriter(new FileWriter(new File("/home/buildClazzFromParser.txt"))));
|
||||||
|
|
||||||
|
reader = new BufferedReader(new FileReader(new File("/home/buildClazzFromParser.txt")));
|
||||||
|
String line;
|
||||||
|
while((line = reader.readLine()) != null) System.out.println(line);
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void mainee(String[] args) throws Exception {
|
||||||
|
File dir = new File("");
|
||||||
|
show(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void mainf(String[] args) throws Exception{
|
||||||
|
String variable = "var myName = \"Test\";";
|
||||||
|
|
||||||
|
String clazz = "package test; public class Test{ "+variable+" }";
|
||||||
|
BufferedWriter writer = new BufferedWriter(new FileWriter(new File("/home/tmp.txt")));
|
||||||
|
writer.write(clazz);
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
|
||||||
|
BufferedReader reader = new BufferedReader(new FileReader(new File("/home/tmp.txt")));
|
||||||
|
|
||||||
|
JavaParser parser = new JavaParser();
|
||||||
|
parser.parse(reader);
|
||||||
|
System.out.println("SHOW-----------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void show(File dir) throws Exception{
|
||||||
|
if(dir.isFile()){
|
||||||
|
if(!dir.getName().endsWith(".java")) return;
|
||||||
|
System.out.println("| "+dir.getAbsolutePath());
|
||||||
|
BufferedReader reader = new BufferedReader(new FileReader(dir));
|
||||||
|
|
||||||
|
try {
|
||||||
|
JavaParser parser = new JavaParser();
|
||||||
|
parser.parse(reader);
|
||||||
|
|
||||||
|
Class clazz = parser.getClazz();
|
||||||
|
System.out.println(clazz.getName());
|
||||||
|
// for(Variable variable : clazz.getVariables()){
|
||||||
|
// variable.show(1);
|
||||||
|
// }
|
||||||
|
}catch(Exception e) {}
|
||||||
|
}else{
|
||||||
|
for(File file : dir.listFiles()) show(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Package pack;
|
||||||
|
private List<Import> imports;
|
||||||
|
private Class clazz;
|
||||||
|
|
||||||
|
//later, maybe put string in the element
|
||||||
|
private CleanerPool cleaner;
|
||||||
|
|
||||||
|
public JavaParser(){}
|
||||||
|
|
||||||
|
public void parse(BufferedReader reader) throws Exception{
|
||||||
|
String content = "";
|
||||||
|
int index;
|
||||||
|
|
||||||
|
cleaner = new CleanerPool(
|
||||||
|
new Cleaner("CONSTANT_STRING",'"','"'),
|
||||||
|
new Cleaner("CONSTANT_CHAR",'\'','\''));
|
||||||
|
|
||||||
|
String line;
|
||||||
|
while((line = reader.readLine()) != null){
|
||||||
|
line = cleaner.clean(line);
|
||||||
|
index = line.indexOf("//");
|
||||||
|
if(index >= 0) line = line.substring(0, index);
|
||||||
|
content+=line+" ";
|
||||||
|
}
|
||||||
|
System.out.println(content);
|
||||||
|
|
||||||
|
this.pack = new Package();
|
||||||
|
index = this.pack.parse(content);
|
||||||
|
content = content.substring(index);
|
||||||
|
|
||||||
|
this.imports = new ArrayList<>();
|
||||||
|
while(Import.isImport(content)){
|
||||||
|
Import imp = new Import();
|
||||||
|
index = imp.parse(content);
|
||||||
|
this.imports.add(imp);
|
||||||
|
content = content.substring(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.clazz = new Class();
|
||||||
|
index = this.clazz.parse(content, cleaner, null);
|
||||||
|
content = content.substring(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <E extends JavaElement> E find(Function<JavaElement, Boolean> search, Function<List<JavaElement>, Boolean> deep){
|
||||||
|
return (E)this.clazz.find(search, deep, new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public <E extends JavaElement> E find(BiFunction<JavaElement, List<JavaElement>, Boolean> search){
|
||||||
|
return (E) this.clazz.find(search, new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Package getPackage(){
|
||||||
|
return this.pack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Import> getImports(){
|
||||||
|
return this.imports;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class getClazz(){
|
||||||
|
return this.clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void build(BufferedWriter writer) throws Exception{
|
||||||
|
writer.write("package "+this.pack.getName()+";\n");
|
||||||
|
writer.write("\n");
|
||||||
|
for(Import element : this.imports) writer.write("import "+element.getName()+";\n");
|
||||||
|
writer.write("\n");
|
||||||
|
|
||||||
|
ArrayBuffer<String> buffer = new ArrayBuffer<String>(String.class);
|
||||||
|
buffer.add("");
|
||||||
|
this.clazz.build(buffer, 0);
|
||||||
|
|
||||||
|
Iterator<String> lines = buffer.iterator();
|
||||||
|
while(lines.hasNext()){
|
||||||
|
String line = lines.next();
|
||||||
|
line = this.cleaner.unzip(line, (s,p) -> s);
|
||||||
|
writer.write(line+"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static int getModifier(String modifier){
|
||||||
|
switch(modifier){
|
||||||
|
case "public": return Modifier.PUBLIC;
|
||||||
|
case "private": return Modifier.PRIVATE;
|
||||||
|
case "protected": return Modifier.PROTECTED;
|
||||||
|
case "static": return Modifier.STATIC;
|
||||||
|
case "final": return Modifier.FINAL;
|
||||||
|
case "synchronized": return Modifier.SYNCHRONIZED;
|
||||||
|
case "volatile": return Modifier.VOLATILE;
|
||||||
|
case "transient": return Modifier.TRANSIENT;
|
||||||
|
case "native": return Modifier.NATIVE;
|
||||||
|
case "abstract": return Modifier.ABSTRACT;
|
||||||
|
case "strictfp": return Modifier.STRICT;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
24
src/be/jeffcheasey88/peeratcode/parser/java/Package.java
Normal file
24
src/be/jeffcheasey88/peeratcode/parser/java/Package.java
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class Package {
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*package\\s+([^;]*);)");
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Package(){}
|
||||||
|
|
||||||
|
public int parse(String content) throws Exception{
|
||||||
|
Matcher matcher = PATTERN.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
this.name = matcher.group(2);
|
||||||
|
return matcher.group(1).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName(){
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
}
|
235
src/be/jeffcheasey88/peeratcode/parser/java/Variable.java
Normal file
235
src/be/jeffcheasey88/peeratcode/parser/java/Variable.java
Normal file
|
@ -0,0 +1,235 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java;
|
||||||
|
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool.Cleaner;
|
||||||
|
|
||||||
|
public class Variable extends JavaElement{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*)(.*)$");
|
||||||
|
|
||||||
|
private List<Annotation> annotations;
|
||||||
|
|
||||||
|
private int modifier;
|
||||||
|
private String name;
|
||||||
|
private String type;
|
||||||
|
private Variable value; //Change into operation or JavaElement
|
||||||
|
|
||||||
|
public Variable(){
|
||||||
|
this.annotations = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Variable(int modifier, String type){
|
||||||
|
this();
|
||||||
|
this.modifier = modifier;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
CleanerPool generic = new CleanerPool(
|
||||||
|
new Cleaner("GENERIC_TYPE",'<','>'),
|
||||||
|
new Cleaner("GENERIC_ARRAY",'[',']'),
|
||||||
|
new Cleaner("GENERIC_FUNCTION", '{','}'),
|
||||||
|
new Cleaner("GENERIC_PARENTHESIS",'(',')'));
|
||||||
|
if(local == null) local = generic;
|
||||||
|
else local = local.group(generic);
|
||||||
|
content = local.clean(content);
|
||||||
|
|
||||||
|
Matcher matcher = PATTERN.matcher(content);
|
||||||
|
matcher.matches();
|
||||||
|
|
||||||
|
int offset = matcher.group(1).length();
|
||||||
|
|
||||||
|
String body = matcher.group(2);
|
||||||
|
int equals = indexOf(body, "=");
|
||||||
|
int quote = indexOf(body,",");
|
||||||
|
int quotes = indexOf(body, ";");
|
||||||
|
int min = Math.min(quote, quotes);
|
||||||
|
body = body.substring(0, min);
|
||||||
|
|
||||||
|
if(equals < quote && equals < quotes){
|
||||||
|
assigment(body, local);
|
||||||
|
}else{
|
||||||
|
onlyDefine(body, local);
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset+local.unzipOne(body, (s,p) -> (p.equals("^GENERIC_TYPE") || p.equals("^GENERIC_ARRAY")) ? s : null).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assigment(String content, CleanerPool cleaner) throws Exception{
|
||||||
|
Iterator<String> values = onlyDefine(content, cleaner);
|
||||||
|
if(!values.hasNext()) return;
|
||||||
|
values.next();
|
||||||
|
if(!values.hasNext()) return;
|
||||||
|
String spacesValue = values.next();
|
||||||
|
while(values.hasNext()) spacesValue+=" "+values.next();
|
||||||
|
this.value = new Value(spacesValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Iterator<String> onlyDefine(String content, CleanerPool cleaner) throws Exception{
|
||||||
|
content = generiqueTypes(content, cleaner);
|
||||||
|
|
||||||
|
CleanerPool tmp = new CleanerPool(new Cleaner("GENERIC_PARENTHESIS",'(',')'));
|
||||||
|
content = tmp.clean(content);
|
||||||
|
|
||||||
|
String[] array = content.split("\\s+");
|
||||||
|
// for(int i = 0; i < array.length; i++) array[i] = tmp.unzip(array[i], (s,p) -> s);
|
||||||
|
Iterator<String> values = new ArrayIterator<>(array);
|
||||||
|
String value = null;
|
||||||
|
int modifier;
|
||||||
|
while(values.hasNext() && ((value = values.next()).charAt(0) == '@')){
|
||||||
|
Annotation annotation = new Annotation();
|
||||||
|
annotation.parse(value, cleaner, tmp);
|
||||||
|
this.annotations.add(annotation);
|
||||||
|
}
|
||||||
|
if((modifier = JavaParser.getModifier(value)) > 0){
|
||||||
|
do{
|
||||||
|
this.modifier+=modifier;
|
||||||
|
}while(values.hasNext() && (modifier = JavaParser.getModifier(value = values.next())) > 0);
|
||||||
|
}
|
||||||
|
if(this.type == null){
|
||||||
|
this.type = value;
|
||||||
|
if(values.hasNext()) value = values.next();
|
||||||
|
}
|
||||||
|
if(this.name == null){
|
||||||
|
this.name = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Pattern UNZIP_STICK = Pattern.compile("\\s+(?<e>[<|(|\\[|\"|'])");
|
||||||
|
private static Pattern UNZIP_MAJ = Pattern.compile(">(?<e>[^>\\d,;(])");
|
||||||
|
private static Pattern UNZIP_ARRAY = Pattern.compile("](?<e>[^\\[\\d,;])");
|
||||||
|
private static Pattern UNZIP_EQUALS_LEFT = Pattern.compile("(?<e>[^=\\s])=");
|
||||||
|
private static Pattern UNZIP_EQUALS_RIGHT = Pattern.compile("=(?<e>[^=\\s])");
|
||||||
|
|
||||||
|
private String generiqueTypes(String content, CleanerPool cleaner){
|
||||||
|
String unzip = cleaner.unzip(content, (value, pattern) -> {
|
||||||
|
if(pattern.equals("^GENERIC_FUNCTION")) return null;
|
||||||
|
if(pattern.equals("^GENERIC_PARENTHESIS")) return value.replace("\\s+", " ");
|
||||||
|
return value.replaceAll("\\s+", "");
|
||||||
|
});
|
||||||
|
unzip = UNZIP_STICK.matcher(unzip).replaceAll("${e}");
|
||||||
|
unzip = UNZIP_MAJ.matcher(unzip).replaceAll("> ${e}");
|
||||||
|
unzip = UNZIP_ARRAY.matcher(unzip).replaceAll("] ${e}");
|
||||||
|
unzip = UNZIP_EQUALS_LEFT.matcher(unzip).replaceAll("${e} =");
|
||||||
|
unzip = UNZIP_EQUALS_RIGHT.matcher(unzip).replaceAll("= ${e}");
|
||||||
|
return unzip;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int indexOf(String value, String target){
|
||||||
|
return value.split(target)[0].length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getModifier(){
|
||||||
|
return this.modifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName(){
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType(){
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Variable getValue(){
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Annotation> getAnnotations(){
|
||||||
|
return this.annotations;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
super.build(buffer, tab);
|
||||||
|
for(Annotation annotation : this.annotations){
|
||||||
|
annotation.build(buffer, 0);
|
||||||
|
buffer.append((s) -> s+=" ");
|
||||||
|
}
|
||||||
|
buffer.append((s) -> s+=Modifier.toString(modifier)+(modifier > 0 ? " ":"")+type+" "+name+(value == null ? ";":" = "+value+";"));
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(java.util.function.Function<JavaElement, Boolean> search, java.util.function.Function<List<JavaElement>, Boolean> deep, List<JavaElement> trace){
|
||||||
|
if(search.apply(this)) return (E)this;
|
||||||
|
trace.add(this);
|
||||||
|
int index = trace.size()-1;
|
||||||
|
if(!deep.apply(trace)) return null;
|
||||||
|
//Value of the variable
|
||||||
|
trace.remove(index);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(BiFunction<JavaElement, List<JavaElement>, Boolean> search, List<JavaElement> trace){
|
||||||
|
trace.add(this);
|
||||||
|
int index = trace.size()-1;
|
||||||
|
if(search.apply(this, trace)) return (E)this;
|
||||||
|
//value
|
||||||
|
trace.remove(index);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Value extends Variable{
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public Value(String value){
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String value(){
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(){
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MultipleDeclaratedVariable extends Variable{
|
||||||
|
|
||||||
|
private List<String> names;
|
||||||
|
private List<Variable> values;
|
||||||
|
|
||||||
|
public MultipleDeclaratedVariable(int modifier, String type){
|
||||||
|
super(modifier, type);
|
||||||
|
this.names = new ArrayList<>();
|
||||||
|
this.values = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addVariable(String name, Variable value){
|
||||||
|
this.names.add(name);
|
||||||
|
this.values.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception {
|
||||||
|
String spacement = "";
|
||||||
|
for(int i = 0; i < tab; i++) spacement+="\t";
|
||||||
|
final String sMod = spacement;
|
||||||
|
|
||||||
|
String vars = "";
|
||||||
|
for(int i = 0; i < this.names.size(); i++){
|
||||||
|
Variable value = this.values.get(i);
|
||||||
|
vars+=","+this.names.get(i)+((value == null) ? "" : " = "+value);
|
||||||
|
}
|
||||||
|
vars = vars.substring(1);
|
||||||
|
String varMod = vars;
|
||||||
|
buffer.append((s) -> s+=sMod+Modifier.toString(getModifier())+" "+getType()+" "+varMod+";");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java.operations;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.ArrayBuffer;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.JavaElement;
|
||||||
|
|
||||||
|
public class AssigmentOperation extends JavaElement{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*([^\\s]+)\\s*=\\s*([^;]+);)");
|
||||||
|
|
||||||
|
private String variable;
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public AssigmentOperation(){}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
Matcher matcher = PATTERN.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
this.variable = local.unzip(matcher.group(2), (s,p) -> s);
|
||||||
|
this.value = local.unzip(matcher.group(3), (s,p) -> s);
|
||||||
|
|
||||||
|
return matcher.group(1).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+=variable+" = "+value+";");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(java.util.function.Function<JavaElement, Boolean> search, java.util.function.Function<List<JavaElement>, Boolean> deep, List<JavaElement> trace){
|
||||||
|
if(search.apply(this)) return (E)this;
|
||||||
|
trace.add(this);
|
||||||
|
int index = trace.size()-1;
|
||||||
|
if(!deep.apply(trace)) return null;
|
||||||
|
//value
|
||||||
|
trace.remove(index);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(BiFunction<JavaElement, List<JavaElement>, Boolean> search, List<JavaElement> trace){
|
||||||
|
trace.add(this);
|
||||||
|
int index = trace.size()-1;
|
||||||
|
if(search.apply(this, trace)) return (E)this;
|
||||||
|
//value
|
||||||
|
trace.remove(index);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java.operations;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.ArrayBuffer;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.JavaElement;
|
||||||
|
|
||||||
|
public class ConditionalOperation extends OperationContainer{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\^GENERIC_FUNCTION\\d+)");
|
||||||
|
private static Pattern PATTERN_SPACE = Pattern.compile("^(\\s+)");
|
||||||
|
|
||||||
|
private Pattern pattern;
|
||||||
|
private String condition;
|
||||||
|
|
||||||
|
public ConditionalOperation(Pattern pattern){
|
||||||
|
this.pattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
Matcher matcher = this.pattern.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
this.condition = local.unzipOne(matcher.group(2), (s,p) -> s);
|
||||||
|
// System.out.println("CONDITION "+condition);
|
||||||
|
|
||||||
|
int index = matcher.group(1).length();
|
||||||
|
content = content.substring(index);
|
||||||
|
|
||||||
|
matcher = PATTERN_SPACE.matcher(content);
|
||||||
|
if(matcher.lookingAt()){
|
||||||
|
index+=matcher.group(1).length();
|
||||||
|
content = content.substring(matcher.group(1).length());
|
||||||
|
}
|
||||||
|
|
||||||
|
int bodysize;
|
||||||
|
if(content.startsWith("^")){
|
||||||
|
matcher = PATTERN.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
content = matcher.group(1);
|
||||||
|
|
||||||
|
bodysize = content.length();
|
||||||
|
content = local.unzipOne(content, (s,p) -> s);
|
||||||
|
content = content.substring(1, content.length()-1);
|
||||||
|
content = local.clean(content);
|
||||||
|
super.parse(content, global, local);
|
||||||
|
}else if(content.startsWith(";")){
|
||||||
|
bodysize=1;
|
||||||
|
}else{
|
||||||
|
bodysize = parseOne(content, global, local);
|
||||||
|
}
|
||||||
|
|
||||||
|
return index+bodysize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
boolean empty = getChilds().size() == 0;
|
||||||
|
if(empty){
|
||||||
|
buffer.append((s) -> s+=";");
|
||||||
|
buffer.add("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean oneChild = getChilds().size() == 1;
|
||||||
|
if(oneChild) buffer.append((s) -> s+=" ");
|
||||||
|
else{
|
||||||
|
buffer.append((s) -> s+="{");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(JavaElement child : getChilds()) child.build(buffer, oneChild ? 0 : tab+1);
|
||||||
|
|
||||||
|
if(!oneChild){
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="}");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class IfOperation extends ConditionalOperation{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*if\\s*(\\^GENERIC_PARENTHESIS\\d+))");
|
||||||
|
|
||||||
|
public IfOperation(){
|
||||||
|
super(PATTERN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
String spacement = "";
|
||||||
|
for(int i = 0; i < tab; i++) spacement+="\t";
|
||||||
|
final String modSpace = spacement;
|
||||||
|
buffer.append((s) -> s+=modSpace+"if"+super.condition);
|
||||||
|
|
||||||
|
super.build(buffer, tab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ForOperation extends ConditionalOperation{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*for\\s*(\\^GENERIC_PARENTHESIS\\d+))");
|
||||||
|
|
||||||
|
public ForOperation(){
|
||||||
|
super(PATTERN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
String spacement = "";
|
||||||
|
for(int i = 0; i < tab; i++) spacement+="\t";
|
||||||
|
final String modSpace = spacement;
|
||||||
|
buffer.append((s) -> s+=modSpace+"for"+super.condition);
|
||||||
|
|
||||||
|
super.build(buffer, tab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class WhileOperation extends ConditionalOperation{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*while\\s*(\\^GENERIC_PARENTHESIS\\d+))");
|
||||||
|
|
||||||
|
public WhileOperation(){
|
||||||
|
super(PATTERN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
String spacement = "";
|
||||||
|
for(int i = 0; i < tab; i++) spacement+="\t";
|
||||||
|
final String modSpace = spacement;
|
||||||
|
buffer.append((s) -> s+=modSpace+"while"+super.condition);
|
||||||
|
|
||||||
|
super.build(buffer, tab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java.operations;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.ArrayBuffer;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.JavaElement;
|
||||||
|
|
||||||
|
public class DoOperation extends OperationContainer{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*do\\s*)");
|
||||||
|
private static Pattern PATTERN_CLEANER = Pattern.compile("^(\\^GENERIC_FUNCTION\\d+)");
|
||||||
|
|
||||||
|
public DoOperation(){}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
Matcher matcher = PATTERN.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
int index = matcher.group(1).length();
|
||||||
|
content = content.substring(index);
|
||||||
|
|
||||||
|
matcher = PATTERN_CLEANER.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
content = matcher.group(1);
|
||||||
|
|
||||||
|
index += content.length();
|
||||||
|
content = local.unzipOne(content, (s,p) -> s);
|
||||||
|
content = content.substring(1, content.length()-1);
|
||||||
|
content = local.clean(content);
|
||||||
|
super.parse(content, global, local);
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="do{");
|
||||||
|
buffer.add("");
|
||||||
|
|
||||||
|
for(JavaElement child : getChilds()) child.build(buffer, tab+1);
|
||||||
|
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="}");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java.operations;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.ArrayBuffer;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.JavaElement;
|
||||||
|
|
||||||
|
public class ElseOperation extends OperationContainer{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*else\\s*)");
|
||||||
|
private static Pattern PATTERN_CLEANER = Pattern.compile("^(\\^GENERIC_FUNCTION\\d+)");
|
||||||
|
|
||||||
|
public ElseOperation(){}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
Matcher matcher = PATTERN.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
int index = matcher.group(1).length();
|
||||||
|
content = content.substring(index);
|
||||||
|
|
||||||
|
int bodysize;
|
||||||
|
if(content.startsWith("^")){
|
||||||
|
matcher = PATTERN_CLEANER.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
content = matcher.group(1);
|
||||||
|
|
||||||
|
bodysize = content.length();
|
||||||
|
content = local.unzipOne(content, (s,p) -> s);
|
||||||
|
content = content.substring(1, content.length()-1);
|
||||||
|
content = local.clean(content);
|
||||||
|
super.parse(content, global, local);
|
||||||
|
}else{
|
||||||
|
bodysize = parseOne(content, global, local);
|
||||||
|
}
|
||||||
|
|
||||||
|
return index+bodysize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="else ");
|
||||||
|
|
||||||
|
boolean oneOperation = getChilds().size() == 1;
|
||||||
|
if(oneOperation){
|
||||||
|
getChilds().get(0).build(buffer, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.append((s) -> s+="{");
|
||||||
|
buffer.add("");
|
||||||
|
for(JavaElement child : getChilds()) child.build(buffer, tab+1);
|
||||||
|
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="}");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java.operations;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.ArrayBuffer;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.JavaElement;
|
||||||
|
|
||||||
|
public class LoopAffectOperation extends JavaElement{
|
||||||
|
|
||||||
|
private Pattern pattern;
|
||||||
|
|
||||||
|
public LoopAffectOperation(Pattern pattern){
|
||||||
|
this.pattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
Matcher matcher = this.pattern.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
return matcher.group(1).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(java.util.function.Function<JavaElement, Boolean> search, java.util.function.Function<List<JavaElement>, Boolean> deep, List<JavaElement> trace){
|
||||||
|
return search.apply(this) ? (E)this : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(BiFunction<JavaElement, List<JavaElement>, Boolean> search, List<JavaElement> trace){
|
||||||
|
trace.add(this);
|
||||||
|
return search.apply(this, trace) || trace.remove(trace.size()-1) == null ? (E)this : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ContinueOperation extends LoopAffectOperation{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*continue\\s*;)");
|
||||||
|
|
||||||
|
public ContinueOperation(){
|
||||||
|
super(PATTERN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception {
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="continue;");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BreakOperation extends LoopAffectOperation{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*break\\s*;)");
|
||||||
|
|
||||||
|
public BreakOperation(){
|
||||||
|
super(PATTERN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception {
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="break;");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java.operations;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.ArrayBuffer;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.JavaElement;
|
||||||
|
|
||||||
|
public class MethodCallOperation extends JavaElement{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*([^\\^\\s]+\\^GENERIC_PARENTHESIS\\d+);)");
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public MethodCallOperation(){}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
content = local.clean(content);
|
||||||
|
|
||||||
|
Matcher matcher = PATTERN.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
this.value = local.unzip(matcher.group(2), (s,p) -> s);
|
||||||
|
|
||||||
|
return matcher.group(1).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue(){
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+=value+";");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(java.util.function.Function<JavaElement, Boolean> search, java.util.function.Function<List<JavaElement>, Boolean> deep, List<JavaElement> trace){
|
||||||
|
return search.apply(this) ? (E)this : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(BiFunction<JavaElement, List<JavaElement>, Boolean> search, List<JavaElement> trace){
|
||||||
|
trace.add(this);
|
||||||
|
return search.apply(this, trace) || trace.remove(trace.size()-1) == null ? (E)this : null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java.operations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.JavaElement;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.Variable;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.Variable.MultipleDeclaratedVariable;
|
||||||
|
|
||||||
|
public abstract class OperationContainer extends JavaElement{
|
||||||
|
|
||||||
|
private static OperationFactory FACTORY = OperationFactory.getFactory();
|
||||||
|
|
||||||
|
private List<JavaElement> childs;
|
||||||
|
|
||||||
|
public OperationContainer(){
|
||||||
|
this.childs = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
// System.out.println("OperationContainer.parse -> "+content);
|
||||||
|
while(!(content.replaceAll("\\s+", "").isEmpty())) content = internalParse(content, global, local);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int parseOne(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
// System.out.println("OperationContainer.parseOne -> "+content);
|
||||||
|
String modify = internalParse(content, global, local);
|
||||||
|
return content.length()-modify.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String internalParse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
// System.out.println("OperationContainer.internalParse -> "+content);
|
||||||
|
JavaElement operation = FACTORY.buildOperation(content);
|
||||||
|
|
||||||
|
// System.out.println(operation.getClass().getSimpleName()+" operation = FACTORY.buildOperation();");
|
||||||
|
int index = operation.parse(content, global, local);
|
||||||
|
content = content.substring(index);
|
||||||
|
if(operation instanceof Variable){
|
||||||
|
if(content.startsWith(",")){
|
||||||
|
Variable variable = (Variable)operation;
|
||||||
|
MultipleDeclaratedVariable multiple = new MultipleDeclaratedVariable(variable.getModifier(), variable.getType());
|
||||||
|
multiple.addVariable(variable.getName(), variable.getValue());
|
||||||
|
|
||||||
|
operation = multiple;
|
||||||
|
|
||||||
|
boolean quote;
|
||||||
|
do{
|
||||||
|
variable = new Variable(variable.getModifier(), variable.getType());
|
||||||
|
index = variable.parse(content, global, local);
|
||||||
|
multiple.addVariable(variable.getName(), variable.getValue());
|
||||||
|
content = content.substring(index);
|
||||||
|
quote = content.startsWith(",");
|
||||||
|
content = content.substring(1);
|
||||||
|
}while(quote);
|
||||||
|
}else content = content.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.childs.add(operation);
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JavaElement> getChilds(){
|
||||||
|
return this.childs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(java.util.function.Function<JavaElement, Boolean> search, java.util.function.Function<List<JavaElement>, Boolean> deep, List<JavaElement> trace){
|
||||||
|
if(search.apply(this)) return (E)this;
|
||||||
|
trace.add(this);
|
||||||
|
int index = trace.size()-1;
|
||||||
|
if(!deep.apply(trace)) return null;
|
||||||
|
for(JavaElement element : this.childs){
|
||||||
|
E result = element.find(search, deep, trace);
|
||||||
|
if(result != null) return result;
|
||||||
|
}
|
||||||
|
trace.remove(index);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(BiFunction<JavaElement, List<JavaElement>, Boolean> search, List<JavaElement> trace){
|
||||||
|
trace.add(this);
|
||||||
|
int index = trace.size()-1;
|
||||||
|
if(search.apply(this, trace)) return (E)this;
|
||||||
|
for(JavaElement element : this.childs){
|
||||||
|
E result = element.find(search, trace);
|
||||||
|
if(result != null) return result;
|
||||||
|
}
|
||||||
|
trace.remove(index);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java.operations;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool.Cleaner;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.JavaElement;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.Variable;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.operations.ConditionalOperation.ForOperation;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.operations.ConditionalOperation.IfOperation;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.operations.ConditionalOperation.WhileOperation;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.operations.LoopAffectOperation.BreakOperation;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.operations.LoopAffectOperation.ContinueOperation;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.operations.TryCatchOperation.CatchOperation;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.operations.TryCatchOperation.FinallyOperation;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.operations.TryCatchOperation.TryOperation;
|
||||||
|
|
||||||
|
public class OperationFactory{
|
||||||
|
|
||||||
|
private static final OperationFactory SINGLETON = new OperationFactory();
|
||||||
|
|
||||||
|
public static OperationFactory getFactory(){
|
||||||
|
return SINGLETON;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Pattern, Class<? extends JavaElement>> patterns;
|
||||||
|
|
||||||
|
private OperationFactory(){
|
||||||
|
this.patterns = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*return\\s*[^;]*;"), ReturnOperation.class);
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*if\\s*\\^GENERIC_PARENTHESIS\\d+"), IfOperation.class);
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*for\\s*\\^GENERIC_PARENTHESIS\\d+"), ForOperation.class);
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*while\\s*\\^GENERIC_PARENTHESIS\\d+"), WhileOperation.class);
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*else\\s*"), ElseOperation.class);
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*do\\s*\\^GENERIC_FUNCTION\\d+"), DoOperation.class);
|
||||||
|
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*synchronized\\s*\\^GENERIC_PARENTHESIS\\d+"), SynchronizedOperation.class);
|
||||||
|
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*continue\\s*;"), ContinueOperation.class);
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*break\\s*;"), BreakOperation.class);
|
||||||
|
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*throw\\s+[^;]+"), ThrowOperation.class);
|
||||||
|
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*try\\s*\\^"), TryOperation.class);
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*catch\\s*\\^GENERIC_PARENTHESIS\\d+"), CatchOperation.class);
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*finally\\s*\\^GENERIC_FUNCTION\\d+"), FinallyOperation.class);
|
||||||
|
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*[^\\^\\s]+\\^GENERIC_PARENTHESIS\\d+;"), MethodCallOperation.class);
|
||||||
|
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*[^\\s]+\\s+[^\\s]+\\s*=\\s*[^;]+;"), Variable.class);
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*[^\\s]+\\s*=\\s*[^;]+;"), AssigmentOperation.class);
|
||||||
|
this.patterns.put(Pattern.compile("^\\s*[^;]+;"), Variable.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* variable OK
|
||||||
|
* assignation OK
|
||||||
|
* exec method OK
|
||||||
|
* for OK
|
||||||
|
* do while OK
|
||||||
|
* while OK
|
||||||
|
* if OK
|
||||||
|
* switch case
|
||||||
|
* return OK
|
||||||
|
* continue OK
|
||||||
|
* break OK
|
||||||
|
* try catch finally OK
|
||||||
|
* throw OK
|
||||||
|
* else OK
|
||||||
|
* synchronized OK
|
||||||
|
* instance of
|
||||||
|
*
|
||||||
|
* native operation style i++
|
||||||
|
*
|
||||||
|
* assert ??
|
||||||
|
* Goto ??
|
||||||
|
* Const ??
|
||||||
|
*/
|
||||||
|
|
||||||
|
public JavaElement buildOperation(String content) throws Exception{
|
||||||
|
// System.out.println("Factory.buildOperation -> "+content);
|
||||||
|
CleanerPool generic = new CleanerPool(
|
||||||
|
new Cleaner("GENERIC_ARRAY",'[',']'),
|
||||||
|
new Cleaner("GENERIC_TYPE_",'<','>'));
|
||||||
|
content = generic.clean(content);
|
||||||
|
content = generiqueTypes(content, generic);
|
||||||
|
|
||||||
|
for(Entry<Pattern, Class<? extends JavaElement>> entries : this.patterns.entrySet()){
|
||||||
|
if(entries.getKey().matcher(content).lookingAt()) return entries.getValue().newInstance();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Pattern UNZIP_STICK = Pattern.compile("\\s+(?<e>[<|(|\\[|\"|'])");
|
||||||
|
private static Pattern UNZIP_MAJ = Pattern.compile(">(?<e>[^>\\d,;(])");
|
||||||
|
private static Pattern UNZIP_ARRAY = Pattern.compile("](?<e>[^\\[\\d,;])");
|
||||||
|
private static Pattern UNZIP_EQUALS_LEFT = Pattern.compile("(?<e>[^=\\s])=");
|
||||||
|
private static Pattern UNZIP_EQUALS_RIGHT = Pattern.compile("=(?<e>[^=\\s])");
|
||||||
|
|
||||||
|
private String generiqueTypes(String content, CleanerPool cleaner){
|
||||||
|
String unzip = cleaner.unzip(content, (value, pattern) -> {
|
||||||
|
if(pattern.equals("^GENERIC_FUNCTION") || pattern.equals("^GENERIC_PARENTHESIS")) return null;
|
||||||
|
return value.replaceAll("\\s+", "");
|
||||||
|
});
|
||||||
|
unzip = UNZIP_STICK.matcher(unzip).replaceAll("${e}");
|
||||||
|
unzip = UNZIP_MAJ.matcher(unzip).replaceAll("> ${e}");
|
||||||
|
unzip = UNZIP_ARRAY.matcher(unzip).replaceAll("] ${e}");
|
||||||
|
unzip = UNZIP_EQUALS_LEFT.matcher(unzip).replaceAll("${e} =");
|
||||||
|
unzip = UNZIP_EQUALS_RIGHT.matcher(unzip).replaceAll("= ${e}");
|
||||||
|
return unzip;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java.operations;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.ArrayBuffer;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.JavaElement;
|
||||||
|
|
||||||
|
public class ReturnOperation extends JavaElement{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*return\\s*([^;]*);)");
|
||||||
|
|
||||||
|
private static OperationFactory FACTORY = OperationFactory.getFactory();
|
||||||
|
|
||||||
|
private String toChange;
|
||||||
|
private JavaElement value;
|
||||||
|
|
||||||
|
public ReturnOperation(){}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
Matcher matcher = PATTERN.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
//To update for native obj
|
||||||
|
this.toChange = matcher.group(2);
|
||||||
|
JavaElement operation = FACTORY.buildOperation(toChange+";");
|
||||||
|
if(operation != null){
|
||||||
|
System.out.println(operation.getClass().getSimpleName());
|
||||||
|
value = operation;
|
||||||
|
value.parse(toChange+";", global, local);
|
||||||
|
}
|
||||||
|
|
||||||
|
return matcher.group(1).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
super.build(buffer, tab);
|
||||||
|
if(value != null){
|
||||||
|
buffer.append((s) -> s+="return ");
|
||||||
|
value.build(buffer, 0);
|
||||||
|
buffer.add("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
buffer.append((s) -> s+="return "+toChange+";");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(java.util.function.Function<JavaElement, Boolean> search, java.util.function.Function<List<JavaElement>, Boolean> deep, List<JavaElement> trace){
|
||||||
|
if(search.apply(this)) return (E)this;
|
||||||
|
trace.add(this);
|
||||||
|
int index = trace.size()-1;
|
||||||
|
if(!deep.apply(trace)) return null;
|
||||||
|
E result = value.find(search, deep, trace);
|
||||||
|
if(result != null) return result;
|
||||||
|
trace.remove(index);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(BiFunction<JavaElement, List<JavaElement>, Boolean> search, List<JavaElement> trace){
|
||||||
|
trace.add(this);
|
||||||
|
int index = trace.size()-1;
|
||||||
|
if(search.apply(this, trace)) return (E)this;
|
||||||
|
E result = value.find(search, trace);
|
||||||
|
if(result != null) return result;
|
||||||
|
trace.remove(index);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java.operations;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.ArrayBuffer;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.JavaElement;
|
||||||
|
|
||||||
|
public class SynchronizedOperation extends OperationContainer{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*synchronized\\s*)(\\^GENERIC_PARENTHESIS\\d+)(\\s*)");
|
||||||
|
private static Pattern PATTERN_CLEANER = Pattern.compile("^(\\^GENERIC_FUNCTION\\d+)");
|
||||||
|
|
||||||
|
private String include;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
Matcher matcher = PATTERN.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
this.include = local.unzip(matcher.group(2), (s,p) -> s);
|
||||||
|
|
||||||
|
int index = matcher.group(1).length()+matcher.group(2).length()+matcher.group(3).length();
|
||||||
|
content = content.substring(index);
|
||||||
|
|
||||||
|
matcher = PATTERN_CLEANER.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
content = matcher.group(1);
|
||||||
|
|
||||||
|
index += content.length();
|
||||||
|
content = local.unzipOne(content, (s,p) -> s);
|
||||||
|
content = content.substring(1, content.length()-1);
|
||||||
|
content = local.clean(content);
|
||||||
|
super.parse(content, global, local);
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="synchronized"+this.include+"{");
|
||||||
|
buffer.add("");
|
||||||
|
|
||||||
|
for(JavaElement child : getChilds()) child.build(buffer, tab+1);
|
||||||
|
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="}");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java.operations;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.ArrayBuffer;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.JavaElement;
|
||||||
|
|
||||||
|
public class ThrowOperation extends JavaElement{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*throw\\s+([^;]+);)");
|
||||||
|
|
||||||
|
private String toChange;
|
||||||
|
|
||||||
|
public ThrowOperation(){}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception {
|
||||||
|
Matcher matcher = PATTERN.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
//To update for native obj
|
||||||
|
this.toChange = matcher.group(2);
|
||||||
|
|
||||||
|
return matcher.group(1).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="throw "+toChange+";");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(java.util.function.Function<JavaElement, Boolean> search, java.util.function.Function<List<JavaElement>, Boolean> deep, List<JavaElement> trace){
|
||||||
|
return search.apply(this) ? (E)this : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <E extends JavaElement> E find(BiFunction<JavaElement, List<JavaElement>, Boolean> search, List<JavaElement> trace){
|
||||||
|
trace.add(this);
|
||||||
|
return search.apply(this, trace) || trace.remove(trace.size()-1) == null ? (E)this : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,151 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.parser.java.operations;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.ArrayBuffer;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool;
|
||||||
|
import be.jeffcheasey88.peeratcode.parser.java.JavaElement;
|
||||||
|
|
||||||
|
public class TryCatchOperation extends OperationContainer{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\^GENERIC_FUNCTION\\d+)");
|
||||||
|
private static Pattern PATTERN_SPACE = Pattern.compile("^(\\s+)");
|
||||||
|
|
||||||
|
public TryCatchOperation(){}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
Matcher matcher = PATTERN.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
content = matcher.group(1);
|
||||||
|
|
||||||
|
int bodysize = content.length();
|
||||||
|
content = local.unzipOne(content, (s,p) -> s);
|
||||||
|
content = content.substring(1, content.length()-1);
|
||||||
|
content = local.clean(content);
|
||||||
|
super.parse(content, global, local);
|
||||||
|
|
||||||
|
return bodysize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TryOperation extends TryCatchOperation{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*try\\s*(\\^GENERIC_PARENTHESIS\\d+)?)");
|
||||||
|
|
||||||
|
private String resource;
|
||||||
|
|
||||||
|
public TryOperation(){}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
Matcher matcher = TryOperation.PATTERN.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
if(matcher.group(2) != null) this.resource = local.unzipOne(matcher.group(2), (s,p) -> s);
|
||||||
|
|
||||||
|
int index = matcher.group(1).length();
|
||||||
|
content = content.substring(index);
|
||||||
|
|
||||||
|
matcher = PATTERN_SPACE.matcher(content);
|
||||||
|
if(matcher.lookingAt()){
|
||||||
|
index+=matcher.group(1).length();
|
||||||
|
content = content.substring(matcher.group(1).length());
|
||||||
|
}
|
||||||
|
|
||||||
|
return index+super.parse(content, global, local);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="try"+(resource == null ? "":resource)+"{");
|
||||||
|
buffer.add("");
|
||||||
|
|
||||||
|
for(JavaElement child : getChilds()) child.build(buffer, tab+1);
|
||||||
|
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="}");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CatchOperation extends TryCatchOperation{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*catch\\s*(\\^GENERIC_PARENTHESIS\\d+))");
|
||||||
|
|
||||||
|
private String exceptions;
|
||||||
|
|
||||||
|
public CatchOperation(){}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
Matcher matcher = CatchOperation.PATTERN.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
this.exceptions = local.unzipOne(matcher.group(2), (s,p) -> s);
|
||||||
|
|
||||||
|
int index = matcher.group(1).length();
|
||||||
|
content = content.substring(index);
|
||||||
|
|
||||||
|
matcher = PATTERN_SPACE.matcher(content);
|
||||||
|
if(matcher.lookingAt()){
|
||||||
|
index+=matcher.group(1).length();
|
||||||
|
content = content.substring(matcher.group(1).length());
|
||||||
|
}
|
||||||
|
|
||||||
|
return index+super.parse(content, global, local);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="catch"+exceptions+"{");
|
||||||
|
buffer.add("");
|
||||||
|
|
||||||
|
for(JavaElement child : getChilds()) child.build(buffer, tab+1);
|
||||||
|
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="}");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FinallyOperation extends TryCatchOperation{
|
||||||
|
|
||||||
|
private static Pattern PATTERN = Pattern.compile("^(\\s*finally\\s*)");
|
||||||
|
|
||||||
|
public FinallyOperation(){}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
|
||||||
|
Matcher matcher = FinallyOperation.PATTERN.matcher(content);
|
||||||
|
matcher.lookingAt();
|
||||||
|
|
||||||
|
int index = matcher.group(1).length();
|
||||||
|
content = content.substring(index);
|
||||||
|
|
||||||
|
matcher = PATTERN_SPACE.matcher(content);
|
||||||
|
if(matcher.lookingAt()){
|
||||||
|
index+=matcher.group(1).length();
|
||||||
|
content = content.substring(matcher.group(1).length());
|
||||||
|
}
|
||||||
|
|
||||||
|
return index+super.parse(content, global, local);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="finally{");
|
||||||
|
buffer.add("");
|
||||||
|
|
||||||
|
for(JavaElement child : getChilds()) child.build(buffer, tab+1);
|
||||||
|
|
||||||
|
super.build(buffer, tab);
|
||||||
|
buffer.append((s) -> s+="}");
|
||||||
|
buffer.add("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
259
src/be/jeffcheasey88/peeratcode/repository/DatabaseQuery.java
Normal file
259
src/be/jeffcheasey88/peeratcode/repository/DatabaseQuery.java
Normal file
|
@ -0,0 +1,259 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.repository;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public enum DatabaseQuery {
|
||||||
|
// PUZZLES
|
||||||
|
SPECIFIC_PUZZLE_QUERY(
|
||||||
|
"SELECT p.*, np.origin, GROUP_CONCAT(t.name) AS tags FROM puzzles p LEFT JOIN nextPart np ON p.id_puzzle = np.next LEFT JOIN containsTags ct ON ct.fk_puzzle = p.id_puzzle LEFT JOIN tags t ON t.id_tag = ct.fk_tag WHERE p.id_puzzle = ? GROUP BY p.id_puzzle"),
|
||||||
|
PUZZLES_IN_CHAPTER_QUERY(
|
||||||
|
"SELECT p.*, GROUP_CONCAT(t.name) AS tags FROM puzzles p LEFT JOIN containsTags ct ON ct.fk_puzzle = p.id_puzzle LEFT JOIN tags t ON t.id_tag = ct.fk_tag WHERE fk_chapter = ? GROUP BY p.id_puzzle"),
|
||||||
|
|
||||||
|
// CHAPTERS
|
||||||
|
SPECIFIC_CHAPTER_QUERY("SELECT * FROM chapters WHERE id_chapter = ?"),
|
||||||
|
CHAPTER_FROM_PUZZLE("SELECT c.*\r\n"
|
||||||
|
+ "FROM chapters c\r\n"
|
||||||
|
+ "JOIN puzzles p ON p.fk_chapter = c.id_chapter\r\n"
|
||||||
|
+ "WHERE p.id_puzzle = ?"),
|
||||||
|
ALL_CHAPTERS_QUERY("SELECT * FROM chapters WHERE id_chapter > 0"),
|
||||||
|
|
||||||
|
// GROUPS
|
||||||
|
ALL_GROUPS("SELECT * FROM groups"),
|
||||||
|
GET_GROUP_FOR_PLAYER("SELECT g.* FROM groups g JOIN containsGroups cg ON cg.fk_group = g.id_group WHERE cg.fk_player = ? AND g.fk_chapter = ?"), // AND g.fk_puzzle = ?
|
||||||
|
GET_GROUP_ID_BY_DATA("SELECT id_group FROM groups WHERE name = ? AND (fk_chapter = ?)"), // OR fk_puzzle = ?
|
||||||
|
INSERT_GROUP("INSERT INTO groups (name, fk_chapter) VALUES (?,?)"),
|
||||||
|
INSERT_PLAYER_IN_GROUP("INSERT INTO containsGroups (fk_player, fk_group) VALUES (?,?)"),
|
||||||
|
LEAVE_GROUP("DELETE FROM containsGroups WHERE fk_player = ? AND fk_group = ?"),
|
||||||
|
|
||||||
|
// LEADERBOARD
|
||||||
|
ALL_PLAYERS_FOR_LEADERBOARD(
|
||||||
|
"select p.*, scores.*, g.* from players p ,(SELECT fk_player, SUM(c.score) AS score, COUNT(c.id_completion) AS completions, SUM(c.tries) AS tries, rank() over(ORDER BY score DESC) AS rank FROM completions c GROUP BY c.fk_player) AS scores LEFT JOIN containsGroups cg ON scores.fk_player = cg.fk_player LEFT JOIN groups g ON cg.fk_group = g.id_group WHERE p.id_player = scores.fk_player ORDER BY g.fk_chapter"),
|
||||||
|
ALL_GROUP_FOR_CHAPTER_LEADERBOARD(
|
||||||
|
"SELECT g.*, pl.pseudo, co.score, co.tries FROM groups g LEFT JOIN containsGroups cg ON g.id_group = cg.fk_group LEFT JOIN players pl ON cg.fk_player = pl.id_player LEFT JOIN completions co ON pl.id_player = co.fk_player WHERE cg.fk_player IS NOT NULL AND fk_chapter = ? AND (co.fk_puzzle IN (SELECT id_puzzle FROM puzzles puz WHERE puz.fk_chapter = g.fk_chapter) OR co.score IS NULL);"),
|
||||||
|
|
||||||
|
// REGISTER
|
||||||
|
CHECK_PSEUDO_AVAILABLE_QUERY("SELECT * FROM players WHERE pseudo = ?"),
|
||||||
|
CHECK_EMAIL_AVAILABLE_QUERY("SELECT * FROM players WHERE email = ?"),
|
||||||
|
REGISTER_QUERY(
|
||||||
|
"INSERT INTO players (pseudo, email, passwd, firstname, lastname, description, avatar) VALUES (?, ?, ?, ?, ?, ?, ?)"),
|
||||||
|
REGISTER_PLAYER_IN_EXISTING_GROUP(
|
||||||
|
"INSERT INTO containsGroups (fk_player, fk_group) VALUES (?, (SELECT id_group FROM groups WHERE name = ?));"),
|
||||||
|
|
||||||
|
// LOGIN
|
||||||
|
CHECK_PASSWORD("SELECT id_player, passwd FROM players WHERE pseudo=?"),
|
||||||
|
|
||||||
|
// COMPLETIONS
|
||||||
|
GET_COMPLETION(
|
||||||
|
"SELECT * FROM completions WHERE fk_puzzle = ? AND fk_player = ?"),
|
||||||
|
GET_COMPLETION_GROUP("SELECT c.*\r\n"
|
||||||
|
+ "FROM completions c\r\n"
|
||||||
|
+ "JOIN containsGroups cG on c.fk_player = cG.fk_player\r\n"
|
||||||
|
+ "JOIN containsGroups cGs on cGs.fk_group = cG.fk_group\r\n"
|
||||||
|
+ "JOIN groups g on cG.fk_group = g.id_group\r\n"
|
||||||
|
+ "JOIN puzzles p on p.id_puzzle = c.fk_puzzle\r\n"
|
||||||
|
+ "WHERE cGs.fk_player = ? AND p.id_puzzle = ?"),
|
||||||
|
INSERT_COMPLETION(
|
||||||
|
"INSERT INTO completions (fk_puzzle, fk_player, tries, code, fileName, score) values (?, ?, ?, ?, ?, ?)"),
|
||||||
|
UPDATE_COMPLETION(
|
||||||
|
"UPDATE completions SET tries = ?, score = ?, fk_player = ? WHERE fk_puzzle = ? AND fk_player = ?"),
|
||||||
|
SCORE("SELECT score FROM completions WHERE fk_player = ? AND fk_puzzle = ?"),
|
||||||
|
SCORE_GROUP("SELECT c.score\r\n"
|
||||||
|
+ "FROM completions c\r\n"
|
||||||
|
+ "JOIN containsGroups cG on c.fk_player = cG.fk_player\r\n"
|
||||||
|
+ "JOIN containsGroups cGs on cGs.fk_group = cG.fk_group\r\n"
|
||||||
|
+ "JOIN groups g on cG.fk_group = g.id_group\r\n"
|
||||||
|
+ "JOIN puzzles p on p.id_puzzle = c.fk_puzzle\r\n"
|
||||||
|
+ "WHERE cGs.fk_player = ? AND p.id_puzzle = ?"),
|
||||||
|
|
||||||
|
// PLAYERS
|
||||||
|
GET_PLAYER_SIMPLE("SELECT pseudo, email, firstname, lastname, description FROM players WHERE id_player = ?"),
|
||||||
|
GET_PLAYER_DETAILS("SELECT p.*, g.*\r\n"
|
||||||
|
+ "FROM players p\r\n"
|
||||||
|
+ "LEFT OUTER JOIN containsGroups cg ON p.id_player = cg.fk_player\r\n"
|
||||||
|
+ "LEFT OUTER JOIN groups g ON cg.fk_group = g.id_group\r\n"
|
||||||
|
+ "LEFT OUTER JOIN completions c on p.id_player = c.fk_player\r\n"
|
||||||
|
+ "WHERE "),
|
||||||
|
GET_PLAYER_DETAILS_BY_ID(GET_PLAYER_DETAILS, " p.id_player = ? GROUP BY g.name ORDER BY g.fk_chapter, g.fk_puzzle;"),
|
||||||
|
GET_PLAYER_DETAILS_BY_PSEUDO(GET_PLAYER_DETAILS, "p.pseudo = ? GROUP BY g.name ORDER BY g.fk_chapter, g.fk_puzzle;"),
|
||||||
|
GET_PLAYER_COMPLETIONS("select c.*, p.name from completions c left join puzzles p on c.fk_puzzle = p.id_puzzle where fk_player = ?;"),
|
||||||
|
GET_PLAYER_RANK("SELECT * FROM (SELECT fk_player, RANK() OVER(ORDER BY SUM(score) DESC) rank FROM completions c LEFT JOIN players p ON p.id_player = c.fk_player GROUP BY fk_player ORDER BY rank) AS ranks WHERE ranks.fk_player = ?;"),
|
||||||
|
|
||||||
|
// BADGES
|
||||||
|
GET_BADGE("SELECT * FROM badges WHERE id_badge = ?"), GET_BADGES_OF_PLAYER(
|
||||||
|
"SELECT * FROM badges b LEFT JOIN containsBadges cb ON cb.fk_badge = b.id_badge WHERE cb.fk_player = ?"),
|
||||||
|
|
||||||
|
//TRIGGER
|
||||||
|
FIRST_TRY("CREATE OR REPLACE TRIGGER FirstTry\r\n"
|
||||||
|
+ "AFTER INSERT\r\n"
|
||||||
|
+ " ON completions FOR EACH ROW\r\n"
|
||||||
|
+ "BEGIN\r\n"
|
||||||
|
+ " DECLARE badge INT;\r\n"
|
||||||
|
+ " DECLARE contain INT;\r\n"
|
||||||
|
+ " \r\n"
|
||||||
|
+ " SELECT id_badge\r\n"
|
||||||
|
+ " INTO @badge\r\n"
|
||||||
|
+ " FROM badges\r\n"
|
||||||
|
+ " WHERE name = 'FirstTry';\r\n"
|
||||||
|
+ " \r\n"
|
||||||
|
+ " IF @badge is not null THEN\r\n"
|
||||||
|
+ " \r\n"
|
||||||
|
+ " SELECT count(*)\r\n"
|
||||||
|
+ " INTO @contain\r\n"
|
||||||
|
+ " FROM containsBadges\r\n"
|
||||||
|
+ " WHERE fk_badge = @badge AND fk_player = NEW.fk_player;\r\n"
|
||||||
|
+ " \r\n"
|
||||||
|
+ " IF (@contain = 0) THEN\r\n"
|
||||||
|
+ " INSERT INTO containsBadges(fk_player, fk_badge) VALUES (NEW.fk_player, @badge);\r\n"
|
||||||
|
+ " END IF;\r\n"
|
||||||
|
+ " END IF;\r\n"
|
||||||
|
+ "END;"),
|
||||||
|
EventParticipation("CREATE OR REPLACE TRIGGER EventParticipation\r\n"
|
||||||
|
+ "AFTER INSERT\r\n"
|
||||||
|
+ " ON completions FOR EACH ROW\r\n"
|
||||||
|
+ "BEGIN\r\n"
|
||||||
|
+ " DECLARE badge INT;\r\n"
|
||||||
|
+ " DECLARE endDate datetime;\r\n"
|
||||||
|
+ " DECLARE player INT;\r\n"
|
||||||
|
+ " DECLARE contain INT;\r\n"
|
||||||
|
+ "\r\n"
|
||||||
|
+ " SELECT id_badge\r\n"
|
||||||
|
+ " INTO badge\r\n"
|
||||||
|
+ " FROM badges\r\n"
|
||||||
|
+ " WHERE name = 'EventParticipation';\r\n"
|
||||||
|
+ "\r\n"
|
||||||
|
+ " IF @badge is not null THEN\r\n"
|
||||||
|
+ "\r\n"
|
||||||
|
+ " SELECT c.end_date, i.fk_player\r\n"
|
||||||
|
+ " INTO endDate, player\r\n"
|
||||||
|
+ " FROM inserted i\r\n"
|
||||||
|
+ " JOIN puzzles p ON i.fk_puzzle = p.id_puzzle\r\n"
|
||||||
|
+ " JOIN chapters c on p.fk_chapter = c.id_chapter;\r\n"
|
||||||
|
+ "\r\n"
|
||||||
|
+ " IF @endDate is not null THEN\r\n"
|
||||||
|
+ "\r\n"
|
||||||
|
+ " SELECT count(*)\r\n"
|
||||||
|
+ " INTO contain\r\n"
|
||||||
|
+ " FROM containsBadges\r\n"
|
||||||
|
+ " WHERE fk_badge = badge AND fk_player = player;\r\n"
|
||||||
|
+ "\r\n"
|
||||||
|
+ " IF (@contain = 0) THEN\r\n"
|
||||||
|
+ " INSERT INTO containsBadges(fk_player, fk_badge) VALUES (@player, @badge);\r\n"
|
||||||
|
+ " END IF;\r\n"
|
||||||
|
+ " END IF;\r\n"
|
||||||
|
+ " END IF;\r\n"
|
||||||
|
+ "END;");
|
||||||
|
|
||||||
|
private String request;
|
||||||
|
|
||||||
|
DatabaseQuery(DatabaseQuery parent, String request) {
|
||||||
|
this.request = parent.request + request;
|
||||||
|
}
|
||||||
|
|
||||||
|
DatabaseQuery(String request) {
|
||||||
|
this.request = request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedStatement prepare(Connection con) throws SQLException {
|
||||||
|
return con.prepareStatement(this.request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.request;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
|
||||||
|
SELECT p.*, scores.score, scores.completions, scores.tries, scores.rank, g.*
|
||||||
|
FROM players p,
|
||||||
|
(SELECT fk_player, SUM(c.score) AS score,
|
||||||
|
COUNT(c.id_completion) AS completions,
|
||||||
|
SUM(c.tries) AS tries,
|
||||||
|
rank() over(ORDER BY score DESC) AS rank
|
||||||
|
FROM completions c GROUP BY c.fk_player)
|
||||||
|
AS scores
|
||||||
|
LEFT OUTER JOIN containsGroups cg ON scores.fk_player = cg.fk_player
|
||||||
|
LEFT OUTER JOIN groups g ON cg.fk_group = g.id_group
|
||||||
|
WHERE p.id_player = scores.fk_player AND "),
|
||||||
|
|
||||||
|
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* TRIGGER PLACE
|
||||||
|
*
|
||||||
|
|
||||||
|
CREATE OR REPLACE TRIGGER FirstTry
|
||||||
|
AFTER INSERT
|
||||||
|
ON completions FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
DECLARE badge INT;
|
||||||
|
DECLARE contain INT;
|
||||||
|
|
||||||
|
SELECT id_badge
|
||||||
|
INTO @badge
|
||||||
|
FROM badges
|
||||||
|
WHERE name = 'FirstTry';
|
||||||
|
|
||||||
|
IF @badge is not null THEN
|
||||||
|
|
||||||
|
SELECT count(*)
|
||||||
|
INTO @contain
|
||||||
|
FROM containsBadges
|
||||||
|
WHERE fk_badge = @badge AND fk_player = NEW.fk_player;
|
||||||
|
|
||||||
|
IF (@contain = 0) THEN
|
||||||
|
|
||||||
|
IF (NEW.score >= 0 AND NEW.tries < 2) THEN
|
||||||
|
INSERT INTO containsBadges(fk_player, fk_badge) VALUES (NEW.fk_player, @badge);
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE TRIGGER EventParticipation
|
||||||
|
AFTER INSERT
|
||||||
|
ON completions FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
DECLARE badge INT;
|
||||||
|
DECLARE endDate datetime;
|
||||||
|
DECLARE player INT;
|
||||||
|
DECLARE contain INT;
|
||||||
|
|
||||||
|
SELECT id_badge
|
||||||
|
INTO badge
|
||||||
|
FROM badges
|
||||||
|
WHERE name = 'EventParticipation';
|
||||||
|
|
||||||
|
IF @badge is not null THEN
|
||||||
|
|
||||||
|
SELECT c.end_date, i.fk_player
|
||||||
|
INTO endDate, player
|
||||||
|
FROM inserted i
|
||||||
|
JOIN puzzles p ON i.fk_puzzle = p.id_puzzle
|
||||||
|
JOIN chapters c on p.fk_chapter = c.id_chapter;
|
||||||
|
|
||||||
|
IF @endDate is not null THEN
|
||||||
|
|
||||||
|
SELECT count(*)
|
||||||
|
INTO contain
|
||||||
|
FROM containsBadges
|
||||||
|
WHERE fk_badge = badge AND fk_player = player;
|
||||||
|
|
||||||
|
IF (@contain = 0) THEN
|
||||||
|
INSERT INTO containsBadges(fk_player, fk_badge) VALUES (@player, @badge);
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
|
||||||
|
|
||||||
|
*
|
||||||
|
*/
|
|
@ -0,0 +1,699 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.repository;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
import com.password4j.Hash;
|
||||||
|
import com.password4j.Password;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.Configuration;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Badge;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Chapter;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Completion;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Group;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Player;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Puzzle;
|
||||||
|
|
||||||
|
public class DatabaseRepository {
|
||||||
|
|
||||||
|
private Connection con;
|
||||||
|
private Configuration config;
|
||||||
|
|
||||||
|
public DatabaseRepository(Configuration config) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
// testTrigger();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private void testTrigger(){
|
||||||
|
// try {
|
||||||
|
// ensureConnection();
|
||||||
|
// }catch(Exception e){
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
// System.out.println("connection ensured");
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// PreparedStatement log = this.con.prepareStatement("DROP TABLE mycustomlog;");
|
||||||
|
// log.execute();
|
||||||
|
// }catch(Exception e){
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
// System.out.println("log dropped");
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// PreparedStatement log = this.con.prepareStatement("CREATE TABLE mycustomlog(\r\n"
|
||||||
|
// + " message VARCHAR(255),\r\n"
|
||||||
|
// + " primary key (message)\r\n"
|
||||||
|
// + ");");
|
||||||
|
// log.execute();
|
||||||
|
// }catch(Exception e){
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
// System.out.println("log created");
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// System.out.println(DatabaseQuery.FIRST_TRY.toString());
|
||||||
|
// DatabaseQuery.FIRST_TRY.prepare(this.con).execute();
|
||||||
|
// }catch(Exception e){
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// System.out.println("trigger inserted");
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// insertCompletion(new Completion(1, 1, 1, null, 1));
|
||||||
|
// } catch (SQLException e1) {
|
||||||
|
// e1.printStackTrace();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// showLog();
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
// System.out.println("------------------------------");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private void showLog() throws Exception{
|
||||||
|
// ensureConnection();
|
||||||
|
//
|
||||||
|
// PreparedStatement stmt = this.con.prepareStatement("SELECT * FROM mycustomlog");
|
||||||
|
// ResultSet result = stmt.executeQuery();
|
||||||
|
// while(result.next()){
|
||||||
|
// System.out.println("[LOG] "+result.getString("message"));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
private void ensureConnection() throws SQLException {
|
||||||
|
if (con == null || (!con.isValid(5))) {
|
||||||
|
this.con = DriverManager.getConnection(
|
||||||
|
"jdbc:mysql://" + config.getDbHost() + ":" + config.getDbPort() + "/" + config.getDbDatabase() + "",
|
||||||
|
config.getDbUser(), config.getDbPassword());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Puzzle makePuzzle(ResultSet puzzleResult) throws SQLException {
|
||||||
|
return new Puzzle(puzzleResult.getInt("id_puzzle"), puzzleResult.getString("name"),
|
||||||
|
puzzleResult.getString("content"), puzzleResult.getBytes("soluce"), puzzleResult.getString("verify"),
|
||||||
|
puzzleResult.getInt("score_max"), puzzleResult.getString("tags"),
|
||||||
|
hasColumn(puzzleResult, "origin") ? puzzleResult.getInt("origin") : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Chapter makeChapter(ResultSet chapterResult) throws SQLException {
|
||||||
|
return new Chapter(chapterResult.getInt("id_chapter"), chapterResult.getString("name"),
|
||||||
|
chapterResult.getTimestamp("start_date"), chapterResult.getTimestamp("end_date"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Completion makeCompletion(ResultSet completionResult) throws SQLException {
|
||||||
|
String fileName = null;
|
||||||
|
if (hasColumn(completionResult, "fileName"))
|
||||||
|
fileName = completionResult.getString("fileName");
|
||||||
|
String puzzleName = null;
|
||||||
|
if (hasColumn(completionResult, "name"))
|
||||||
|
puzzleName = completionResult.getString("name");
|
||||||
|
|
||||||
|
return new Completion(completionResult.getInt("fk_player"), completionResult.getInt("fk_puzzle"), completionResult.getInt("tries"),
|
||||||
|
fileName, completionResult.getInt("score"), puzzleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Player makePlayer(ResultSet playerResult, int id) throws SQLException {
|
||||||
|
Player p = new Player(playerResult.getString("pseudo"), playerResult.getString("email"),
|
||||||
|
playerResult.getString("firstName"), playerResult.getString("lastName"),
|
||||||
|
playerResult.getString("description"));
|
||||||
|
if (hasColumn(playerResult, "avatar")) {
|
||||||
|
p.setAvatar(playerResult.getBytes("avatar"));
|
||||||
|
}
|
||||||
|
if (hasColumn(playerResult, "score")) {
|
||||||
|
p.addCompletion(new Completion(playerResult.getInt("tries"), playerResult.getInt("score")));
|
||||||
|
for (int ct = 1; ct < playerResult.getInt("completions"); ct++)
|
||||||
|
{ // TODO refactor for V3
|
||||||
|
p.addCompletion(new Completion(0, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Manage groups
|
||||||
|
String groupName = playerResult.getString("name");
|
||||||
|
if (groupName != null) {
|
||||||
|
p.addGroup(makeGroup(playerResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ADD rank
|
||||||
|
PreparedStatement completionsStmt = DatabaseQuery.GET_PLAYER_RANK.prepare(con);
|
||||||
|
completionsStmt.setInt(1, id);
|
||||||
|
ResultSet result = completionsStmt.executeQuery();
|
||||||
|
while (result.next()) {
|
||||||
|
p.setRank(result.getInt("rank"));
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Group makeGroup(ResultSet result) throws SQLException {
|
||||||
|
return new Group(result.getString("name"), result.getInt("fk_chapter"), result.getInt("fk_puzzle"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Player makeGroupPlayer(ResultSet result) throws SQLException {
|
||||||
|
return new Player(result.getString("pseudo"), result.getInt("score"), result.getInt("tries"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Badge makeBadge(ResultSet rs) throws SQLException {
|
||||||
|
return new Badge(rs.getString("name"), rs.getBytes("logo"), rs.getInt("level"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasColumn(ResultSet rs, String columnName) throws SQLException {
|
||||||
|
// Found on StackOverflow
|
||||||
|
ResultSetMetaData rsmd = rs.getMetaData();
|
||||||
|
int columns = rsmd.getColumnCount();
|
||||||
|
for (int x = 1; x <= columns; x++) {
|
||||||
|
if (columnName.equals(rsmd.getColumnName(x)))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Puzzle> getPuzzlesInChapter(int id) throws SQLException {
|
||||||
|
List<Puzzle> puzzles = new ArrayList<>();
|
||||||
|
ensureConnection();
|
||||||
|
PreparedStatement puzzleStmt = DatabaseQuery.PUZZLES_IN_CHAPTER_QUERY.prepare(this.con);
|
||||||
|
puzzleStmt.setInt(1, id);
|
||||||
|
ResultSet puzzleResult = puzzleStmt.executeQuery();
|
||||||
|
while (puzzleResult.next()) {
|
||||||
|
puzzles.add(makePuzzle(puzzleResult));
|
||||||
|
}
|
||||||
|
return puzzles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a specific puzzle
|
||||||
|
*
|
||||||
|
* @param id The id of the puzzle
|
||||||
|
* @return The puzzle or null if an error occurred
|
||||||
|
*/
|
||||||
|
public Puzzle getPuzzle(int id) {
|
||||||
|
try {
|
||||||
|
ensureConnection();
|
||||||
|
PreparedStatement puzzleStmt = DatabaseQuery.SPECIFIC_PUZZLE_QUERY.prepare(this.con);
|
||||||
|
puzzleStmt.setInt(1, id);
|
||||||
|
ResultSet puzzleResult = puzzleStmt.executeQuery();
|
||||||
|
if (puzzleResult.next()) {
|
||||||
|
return makePuzzle(puzzleResult);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getScore(int user, int puzzle) {
|
||||||
|
try {
|
||||||
|
ensureConnection();
|
||||||
|
PreparedStatement stmt = DatabaseQuery.SCORE_GROUP.prepare(this.con);
|
||||||
|
stmt.setInt(1, user);
|
||||||
|
stmt.setInt(2, puzzle);
|
||||||
|
ResultSet result = stmt.executeQuery();
|
||||||
|
if (result.next())
|
||||||
|
return result.getInt("score");
|
||||||
|
|
||||||
|
stmt = DatabaseQuery.SCORE.prepare(this.con);
|
||||||
|
stmt.setInt(1, user);
|
||||||
|
stmt.setInt(2, puzzle);
|
||||||
|
|
||||||
|
result = stmt.executeQuery();
|
||||||
|
if (result.next())
|
||||||
|
return result.getInt("score");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Completion getCompletionGroup(int user, int puzzle) {
|
||||||
|
try {
|
||||||
|
PreparedStatement stmt = DatabaseQuery.GET_COMPLETION_GROUP.prepare(this.con);
|
||||||
|
stmt.setInt(1, user);
|
||||||
|
stmt.setInt(2, puzzle);
|
||||||
|
ResultSet result = stmt.executeQuery();
|
||||||
|
if (result.next())
|
||||||
|
return makeCompletion(result);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return getCompletion(user, puzzle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Completion getCompletion(int playerId, int puzzleId) {
|
||||||
|
try {
|
||||||
|
PreparedStatement completionsStmt = DatabaseQuery.GET_COMPLETION.prepare(this.con);
|
||||||
|
completionsStmt.setInt(1, puzzleId);
|
||||||
|
completionsStmt.setInt(2, playerId);
|
||||||
|
ResultSet result = completionsStmt.executeQuery();
|
||||||
|
if (result.next()) {
|
||||||
|
return makeCompletion(result);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player getPlayer(int idPlayer) {
|
||||||
|
try {
|
||||||
|
PreparedStatement completionsStmt = DatabaseQuery.GET_PLAYER_SIMPLE.prepare(this.con);
|
||||||
|
completionsStmt.setInt(1, idPlayer);
|
||||||
|
ResultSet result = completionsStmt.executeQuery();
|
||||||
|
if (result.next()) {
|
||||||
|
return makePlayer(result, idPlayer);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player getPlayerDetails(int idPlayer) {
|
||||||
|
return getPlayerDetails(idPlayer, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player getPlayerDetails(String pseudoPlayer) {
|
||||||
|
return getPlayerDetails(-1, pseudoPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Player getPlayerDetails(int id, String pseudo) {
|
||||||
|
try {
|
||||||
|
ensureConnection();
|
||||||
|
PreparedStatement completionsStmt;
|
||||||
|
if (pseudo != null) {
|
||||||
|
completionsStmt = DatabaseQuery.GET_PLAYER_DETAILS_BY_PSEUDO.prepare(this.con);
|
||||||
|
completionsStmt.setString(1, pseudo);
|
||||||
|
} else {
|
||||||
|
completionsStmt = DatabaseQuery.GET_PLAYER_DETAILS_BY_ID.prepare(this.con);
|
||||||
|
completionsStmt.setInt(1, id);
|
||||||
|
}
|
||||||
|
ResultSet result = completionsStmt.executeQuery();
|
||||||
|
Player player = null;
|
||||||
|
while (result.next()) {
|
||||||
|
if (player == null) {
|
||||||
|
id = result.getInt("id_player");
|
||||||
|
player = makePlayer(result, id);
|
||||||
|
completionsStmt = DatabaseQuery.GET_BADGES_OF_PLAYER.prepare(this.con);
|
||||||
|
completionsStmt.setInt(1, id);
|
||||||
|
ResultSet resultBadges = completionsStmt.executeQuery();
|
||||||
|
while (resultBadges.next()) {
|
||||||
|
player.addBadge(makeBadge(resultBadges));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
player.addGroup(makeGroup(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ADD completions
|
||||||
|
completionsStmt = DatabaseQuery.GET_PLAYER_COMPLETIONS.prepare(con);
|
||||||
|
completionsStmt.setInt(1, id);
|
||||||
|
result = completionsStmt.executeQuery();
|
||||||
|
while (result.next()) {
|
||||||
|
player.addCompletion(makeCompletion(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
return player;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SortedSet<Player> getAllPlayerForLeaderboard() {
|
||||||
|
try {
|
||||||
|
ensureConnection();
|
||||||
|
PreparedStatement playersStmt = DatabaseQuery.ALL_PLAYERS_FOR_LEADERBOARD.prepare(this.con);
|
||||||
|
ResultSet result = playersStmt.executeQuery();
|
||||||
|
ArrayList<Player> players = new ArrayList<Player>();
|
||||||
|
Player tmpPlayer;
|
||||||
|
while (result.next()) {
|
||||||
|
tmpPlayer = makePlayer(result, result.getInt("id_player"));
|
||||||
|
if (!players.contains(tmpPlayer)) {
|
||||||
|
players.add(tmpPlayer);
|
||||||
|
} else {
|
||||||
|
players.get(players.indexOf(tmpPlayer)).addGroup(makeGroup(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new TreeSet<Player>(players);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SortedSet<Group> getAllGroupForChapterLeaderboard(int chapterId){
|
||||||
|
try{
|
||||||
|
ensureConnection();
|
||||||
|
PreparedStatement groupsStmt = DatabaseQuery.ALL_GROUP_FOR_CHAPTER_LEADERBOARD.prepare(this.con);
|
||||||
|
groupsStmt.setInt(1, chapterId);
|
||||||
|
ResultSet result = groupsStmt.executeQuery();
|
||||||
|
List<Group> groups = new ArrayList<Group>();
|
||||||
|
Group tmpGroup;
|
||||||
|
while (result.next()) {
|
||||||
|
tmpGroup = makeGroup(result);
|
||||||
|
if (tmpGroup != null) {
|
||||||
|
int gPosition = groups.indexOf(tmpGroup);
|
||||||
|
if (gPosition < 0) {
|
||||||
|
tmpGroup.addPlayer(makeGroupPlayer(result));
|
||||||
|
groups.add(tmpGroup);
|
||||||
|
} else {
|
||||||
|
groups.get(gPosition).addPlayer(makeGroupPlayer(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new TreeSet<Group>(groups);
|
||||||
|
}catch(SQLException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Badge getBadge(int badgeId) {
|
||||||
|
try {
|
||||||
|
ensureConnection();
|
||||||
|
PreparedStatement completionsStmt = DatabaseQuery.GET_BADGE.prepare(this.con);
|
||||||
|
completionsStmt.setInt(1, badgeId);
|
||||||
|
ResultSet result = completionsStmt.executeQuery();
|
||||||
|
if (result.next()) {
|
||||||
|
return makeBadge(result);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a specific chapter
|
||||||
|
*
|
||||||
|
* @param id The id of the chapter
|
||||||
|
* @return The chapter or null if an error occurred
|
||||||
|
*/
|
||||||
|
public Chapter getChapter(int id) {
|
||||||
|
try {
|
||||||
|
ensureConnection();
|
||||||
|
PreparedStatement chapterStmt = DatabaseQuery.SPECIFIC_CHAPTER_QUERY.prepare(this.con);
|
||||||
|
chapterStmt.setInt(1, id);
|
||||||
|
ResultSet chapterResult = chapterStmt.executeQuery();
|
||||||
|
if (chapterResult.next()) {
|
||||||
|
Chapter chapter = makeChapter(chapterResult);
|
||||||
|
List<Puzzle> puzzles = getPuzzlesInChapter(id);
|
||||||
|
chapter.setPuzzles(puzzles);
|
||||||
|
return chapter;
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chapter getChapter(Puzzle puzzle){
|
||||||
|
try {
|
||||||
|
ensureConnection();
|
||||||
|
PreparedStatement chapterStmt = DatabaseQuery.CHAPTER_FROM_PUZZLE.prepare(this.con);
|
||||||
|
chapterStmt.setInt(1, puzzle.getId());
|
||||||
|
ResultSet chapterResult = chapterStmt.executeQuery();
|
||||||
|
if (chapterResult.next()) {
|
||||||
|
Chapter chapter = makeChapter(chapterResult);
|
||||||
|
List<Puzzle> puzzles = getPuzzlesInChapter(chapter.getId());
|
||||||
|
chapter.setPuzzles(puzzles);
|
||||||
|
return chapter;
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all chapters in the database
|
||||||
|
*
|
||||||
|
* @return List of all chapters or null if an error occurred
|
||||||
|
*/
|
||||||
|
public List<Chapter> getAllChapters() {
|
||||||
|
try {
|
||||||
|
List<Chapter> chapterList = new ArrayList<>();
|
||||||
|
ensureConnection();
|
||||||
|
PreparedStatement chapterStmt = DatabaseQuery.ALL_CHAPTERS_QUERY.prepare(this.con);
|
||||||
|
ResultSet chapterResult = chapterStmt.executeQuery();
|
||||||
|
while (chapterResult.next()) {
|
||||||
|
Chapter chapter = makeChapter(chapterResult);
|
||||||
|
chapter.setPuzzles(getPuzzlesInChapter(chapter.getId()));
|
||||||
|
chapterList.add(chapter);
|
||||||
|
}
|
||||||
|
return chapterList;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Group> getAllGroups() {
|
||||||
|
try {
|
||||||
|
ensureConnection();
|
||||||
|
List<Group> list = new ArrayList<>();
|
||||||
|
PreparedStatement stmt = DatabaseQuery.ALL_GROUPS.prepare(this.con);
|
||||||
|
ResultSet groupResult = stmt.executeQuery();
|
||||||
|
while (groupResult.next())
|
||||||
|
list.add(makeGroup(groupResult));
|
||||||
|
return list;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a pseudo is available
|
||||||
|
*
|
||||||
|
* @param pseudo The pseudo to check
|
||||||
|
* @return True if the pseudo is available, false if it's already taken
|
||||||
|
*/
|
||||||
|
public boolean checkPseudoAvailability(String pseudo) {
|
||||||
|
return checkAvailability(pseudo, DatabaseQuery.CHECK_PSEUDO_AVAILABLE_QUERY.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an email is available
|
||||||
|
*
|
||||||
|
* @param email The email to check
|
||||||
|
* @return True if the email is available, false if it's already taken
|
||||||
|
*/
|
||||||
|
public boolean checkEmailAvailability(String email) {
|
||||||
|
return checkAvailability(email, DatabaseQuery.CHECK_EMAIL_AVAILABLE_QUERY.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkAvailability(String queriedString, String correspondingQuery) {
|
||||||
|
try {
|
||||||
|
ensureConnection();
|
||||||
|
PreparedStatement statement = con.prepareStatement(correspondingQuery);
|
||||||
|
statement.setString(1, queriedString);
|
||||||
|
ResultSet result = statement.executeQuery();
|
||||||
|
return !result.next();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new user
|
||||||
|
*
|
||||||
|
* @param pseudo The pseudo of the user
|
||||||
|
* @param email The email of the user
|
||||||
|
* @param password The password of the user
|
||||||
|
* @param firstname The firstname of the user
|
||||||
|
* @param lastname The lastname of the user
|
||||||
|
* @param description The description of the user
|
||||||
|
* @param sgroup The group of the user
|
||||||
|
* @param avatar The avatar of the user
|
||||||
|
* @return True if the user was registered, false if an error occurred
|
||||||
|
*/
|
||||||
|
public int register(String pseudo, String email, String password, String firstname, String lastname,
|
||||||
|
String description, String sgroup, String avatar) {
|
||||||
|
Hash hash = Password.hash(password).withArgon2();
|
||||||
|
try {
|
||||||
|
ensureConnection();
|
||||||
|
con.setAutoCommit(false);
|
||||||
|
try (PreparedStatement playerStatement = con.prepareStatement(DatabaseQuery.REGISTER_QUERY.toString(),
|
||||||
|
Statement.RETURN_GENERATED_KEYS)) {
|
||||||
|
playerStatement.setString(1, pseudo);
|
||||||
|
playerStatement.setString(2, email);
|
||||||
|
playerStatement.setString(3, hash.getResult());
|
||||||
|
playerStatement.setString(4, firstname);
|
||||||
|
playerStatement.setString(5, lastname);
|
||||||
|
playerStatement.setString(6, description);
|
||||||
|
playerStatement.setString(7, avatar);
|
||||||
|
if (playerStatement.executeUpdate() == 1) {
|
||||||
|
ResultSet inserted = playerStatement.getGeneratedKeys();
|
||||||
|
if (inserted.next()) {
|
||||||
|
int newPlayerId = inserted.getInt(1);
|
||||||
|
if (!sgroup.isEmpty()) {
|
||||||
|
try (PreparedStatement containsGroupsStatement = con
|
||||||
|
.prepareStatement(DatabaseQuery.REGISTER_PLAYER_IN_EXISTING_GROUP.toString())) {
|
||||||
|
containsGroupsStatement.setInt(1, newPlayerId);
|
||||||
|
containsGroupsStatement.setString(2, sgroup);
|
||||||
|
containsGroupsStatement.executeUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
con.commit();
|
||||||
|
con.setAutoCommit(true);
|
||||||
|
return newPlayerId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
con.rollback();
|
||||||
|
con.setAutoCommit(true);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Login a user
|
||||||
|
*
|
||||||
|
* @param username The username of the user
|
||||||
|
* @param password The password of the user
|
||||||
|
* @return id the id of the user, -1 if not login successefuly
|
||||||
|
*/
|
||||||
|
public int login(String username, String password) {
|
||||||
|
try {
|
||||||
|
ensureConnection();
|
||||||
|
PreparedStatement statement = con.prepareStatement(DatabaseQuery.CHECK_PASSWORD.toString());
|
||||||
|
DatabaseQuery.PUZZLES_IN_CHAPTER_QUERY.prepare(this.con);
|
||||||
|
statement.setString(1, username);
|
||||||
|
ResultSet result = statement.executeQuery();
|
||||||
|
if (result.next()) {
|
||||||
|
String hashedPassword = result.getString("passwd");
|
||||||
|
if (Password.check(password, hashedPassword).withArgon2())
|
||||||
|
return result.getInt("id_player");
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Completion insertOrUpdatePuzzleResponse(int puzzleId, int userId, String fileName, byte[] code,
|
||||||
|
byte[] response, Puzzle currentPuzzle){
|
||||||
|
try {
|
||||||
|
ensureConnection();
|
||||||
|
Completion completion = getCompletionGroup(userId, puzzleId);
|
||||||
|
if (completion == null){
|
||||||
|
System.out.println("Completion is null");
|
||||||
|
completion = new Completion(userId, puzzleId, fileName, code, response, currentPuzzle);
|
||||||
|
insertCompletion(completion);
|
||||||
|
} else {
|
||||||
|
System.out.println(completion);
|
||||||
|
completion.addTry(currentPuzzle, response);
|
||||||
|
int lastUserId = completion.getPlayerId();
|
||||||
|
completion.updatePlayer(userId);
|
||||||
|
updateCompletion(completion, lastUserId);
|
||||||
|
}
|
||||||
|
return completion;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insertCompletion(Completion newCompletion) throws SQLException {
|
||||||
|
PreparedStatement statement = DatabaseQuery.INSERT_COMPLETION.prepare(this.con);
|
||||||
|
statement.setInt(1, newCompletion.getPuzzleId());
|
||||||
|
statement.setInt(2, newCompletion.getPlayerId());
|
||||||
|
statement.setInt(3, newCompletion.getTries());
|
||||||
|
statement.setBytes(4, newCompletion.getCode());
|
||||||
|
statement.setString(5, newCompletion.getFileName());
|
||||||
|
statement.setInt(6, newCompletion.getScore());
|
||||||
|
statement.executeUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean insertGroup(Group group, User creator) throws SQLException {
|
||||||
|
Integer groupId = getGroupId(group);
|
||||||
|
if (groupId == null)
|
||||||
|
ensureConnection();
|
||||||
|
PreparedStatement statement = DatabaseQuery.INSERT_GROUP.prepare(this.con);
|
||||||
|
statement.setString(1, group.getName());
|
||||||
|
statement.setObject(2, group.getLinkToChapter());
|
||||||
|
// statement.setObject(3, group.getLinkToPuzzle());
|
||||||
|
if (statement.executeUpdate() >= 0)
|
||||||
|
return insertUserInGroup(group, creator);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Group getPlayerGroup(int user, Integer chapter) throws SQLException {
|
||||||
|
ensureConnection();
|
||||||
|
PreparedStatement stmt = DatabaseQuery.GET_GROUP_FOR_PLAYER.prepare(this.con);
|
||||||
|
stmt.setInt(1, user);
|
||||||
|
stmt.setObject(2, chapter);
|
||||||
|
// stmt.setObject(3, puzzle);
|
||||||
|
|
||||||
|
ResultSet result = stmt.executeQuery();
|
||||||
|
if (result.next())
|
||||||
|
return makeGroup(result);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getGroupId(Group group) throws SQLException {
|
||||||
|
ensureConnection();
|
||||||
|
PreparedStatement stmt = DatabaseQuery.GET_GROUP_ID_BY_DATA.prepare(this.con);
|
||||||
|
stmt.setString(1, group.getName());
|
||||||
|
stmt.setObject(2, group.getLinkToChapter());
|
||||||
|
// stmt.setObject(3, group.getLinkToPuzzle());
|
||||||
|
|
||||||
|
ResultSet result = stmt.executeQuery();
|
||||||
|
if (result.next())
|
||||||
|
return result.getInt("id_group");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean insertUserInGroup(Group group, User user) throws SQLException {
|
||||||
|
Integer id = getGroupId(group);
|
||||||
|
Group alreadyInGroup = getPlayerGroup(user.getId(), group.getLinkToChapter());
|
||||||
|
if (id != null && alreadyInGroup == null) {
|
||||||
|
PreparedStatement stmt = DatabaseQuery.INSERT_PLAYER_IN_GROUP.prepare(this.con);
|
||||||
|
|
||||||
|
stmt.setInt(1, user.getId());
|
||||||
|
stmt.setInt(2, id);
|
||||||
|
|
||||||
|
return stmt.executeUpdate() >= 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean leaveGroup(Group group, User user) throws SQLException {
|
||||||
|
Integer id = getGroupId(group);
|
||||||
|
if (id != null) {
|
||||||
|
PreparedStatement stmt = DatabaseQuery.LEAVE_GROUP.prepare(this.con);
|
||||||
|
|
||||||
|
stmt.setInt(1, user.getId());
|
||||||
|
stmt.setInt(2, id);
|
||||||
|
|
||||||
|
return stmt.executeUpdate() >= 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateCompletion(Completion completionToUpdate, int user) throws SQLException{
|
||||||
|
System.out.println("update "+completionToUpdate);
|
||||||
|
PreparedStatement statement = DatabaseQuery.UPDATE_COMPLETION.prepare(this.con);
|
||||||
|
statement.setInt(1, completionToUpdate.getTries());
|
||||||
|
statement.setInt(2, completionToUpdate.getScore());
|
||||||
|
statement.setInt(3, completionToUpdate.getPlayerId());
|
||||||
|
statement.setInt(4, completionToUpdate.getPuzzleId());
|
||||||
|
statement.setInt(5, user);
|
||||||
|
statement.executeUpdate();
|
||||||
|
}
|
||||||
|
}
|
47
src/be/jeffcheasey88/peeratcode/routes/BadgeDetails.java
Normal file
47
src/be/jeffcheasey88/peeratcode/routes/BadgeDetails.java
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.routes;
|
||||||
|
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Badge;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class BadgeDetails implements Response {
|
||||||
|
|
||||||
|
private final DatabaseRepository databaseRepo;
|
||||||
|
|
||||||
|
public BadgeDetails(DatabaseRepository databaseRepo) {
|
||||||
|
this.databaseRepo = databaseRepo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RouteDoc(path = "/badge/<id>", responseCode = 200, responseDescription = "JSON contenant les informations du badge")
|
||||||
|
@RouteDoc(responseCode = 400, responseDescription = "Aucun id donner")
|
||||||
|
|
||||||
|
@Route(path = "^\\/badge\\/([0-9]+)$", needLogin = true)
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
|
||||||
|
if (matcher.groupCount() > 0) {
|
||||||
|
int badgeId = Integer.parseInt(matcher.group(1));
|
||||||
|
Badge badge = databaseRepo.getBadge(badgeId);
|
||||||
|
JSONObject badgeJSON = new JSONObject();
|
||||||
|
if (badge != null) {
|
||||||
|
badgeJSON.put("name", badge.getName());
|
||||||
|
if (badge.getLogo() != null)
|
||||||
|
badgeJSON.put("logo", Base64.getEncoder().encodeToString(badge.getLogo()));
|
||||||
|
badgeJSON.put("level", badge.getLevel());
|
||||||
|
}
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *");
|
||||||
|
writer.write(badgeJSON.toJSONString().replace("\\", ""));
|
||||||
|
} else {
|
||||||
|
writer.response(400, "Access-Control-Allow-Origin: *");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
59
src/be/jeffcheasey88/peeratcode/routes/ChapterElement.java
Normal file
59
src/be/jeffcheasey88/peeratcode/routes/ChapterElement.java
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.routes;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import org.json.simple.JSONArray;
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Chapter;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Puzzle;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class ChapterElement implements Response {
|
||||||
|
|
||||||
|
private final DatabaseRepository databaseRepo;
|
||||||
|
|
||||||
|
public ChapterElement(DatabaseRepository databaseRepo) {
|
||||||
|
this.databaseRepo = databaseRepo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RouteDoc(path = "/chapter/<id>", responseCode = 200, responseDescription = "JSON contenant les informations du chapitre demander")
|
||||||
|
@RouteDoc(responseCode = 400, responseDescription = "Aucun id donner")
|
||||||
|
|
||||||
|
@Route(path = "^\\/chapter\\/([0-9]+)$", needLogin = true)
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception{
|
||||||
|
Chapter chapter = databaseRepo.getChapter(Integer.parseInt(matcher.group(1)));
|
||||||
|
if (chapter != null){
|
||||||
|
JSONObject chapterJSON = new JSONObject();
|
||||||
|
chapterJSON.put("id", chapter.getId());
|
||||||
|
chapterJSON.put("name", chapter.getName());
|
||||||
|
if (chapter.getStartDate() != null)
|
||||||
|
chapterJSON.put("startDate", chapter.getStartDate().toString());
|
||||||
|
if (chapter.getEndDate() != null)
|
||||||
|
chapterJSON.put("endDate", chapter.getEndDate().toString());
|
||||||
|
JSONArray puzzles = new JSONArray();
|
||||||
|
for (Puzzle puzzle : chapter.getPuzzles()){
|
||||||
|
JSONObject puzzleJSON = new JSONObject();
|
||||||
|
puzzleJSON.put("id", puzzle.getId());
|
||||||
|
puzzleJSON.put("name", puzzle.getName());
|
||||||
|
puzzleJSON.put("scoreMax", puzzle.getScoreMax());
|
||||||
|
if (puzzle.getTags() != null) puzzleJSON.put("tags", puzzle.getJsonTags());
|
||||||
|
int score = this.databaseRepo.getScore(user.getId(), puzzle.getId());
|
||||||
|
if(score >= 0) puzzleJSON.put("score", score);
|
||||||
|
puzzles.add(puzzleJSON);
|
||||||
|
}
|
||||||
|
chapterJSON.put("puzzles", puzzles);
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *");
|
||||||
|
writer.write(chapterJSON.toJSONString());
|
||||||
|
} else {
|
||||||
|
writer.response(400, "Access-Control-Allow-Origin: *");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
51
src/be/jeffcheasey88/peeratcode/routes/ChapterList.java
Normal file
51
src/be/jeffcheasey88/peeratcode/routes/ChapterList.java
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.routes;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import org.json.simple.JSONArray;
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Chapter;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class ChapterList implements Response {
|
||||||
|
|
||||||
|
private final DatabaseRepository databaseRepo;
|
||||||
|
|
||||||
|
public ChapterList(DatabaseRepository databaseRepo) {
|
||||||
|
this.databaseRepo = databaseRepo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RouteDoc(path = "/chapters", responseCode = 200, responseDescription = "JSON contenant les informations des chapitres")
|
||||||
|
@RouteDoc(responseCode = 400, responseDescription = "Aucun chapitre trouver")
|
||||||
|
|
||||||
|
@Route(path = "^\\/chapters$", needLogin = true)
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
|
||||||
|
List<Chapter> allChapters = databaseRepo.getAllChapters();
|
||||||
|
if (allChapters != null) {
|
||||||
|
JSONArray chaptersJSON = new JSONArray();
|
||||||
|
for (Chapter chapter : allChapters) {
|
||||||
|
JSONObject chapterJSON = new JSONObject();
|
||||||
|
chapterJSON.put("id", chapter.getId());
|
||||||
|
chapterJSON.put("name", chapter.getName());
|
||||||
|
if (chapter.getStartDate() != null)
|
||||||
|
chapterJSON.put("startDate", chapter.getStartDate().toString());
|
||||||
|
if (chapter.getEndDate() != null)
|
||||||
|
chapterJSON.put("endDate", chapter.getEndDate().toString());
|
||||||
|
chaptersJSON.add(chapterJSON);
|
||||||
|
}
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *");
|
||||||
|
writer.write(chaptersJSON.toJSONString());
|
||||||
|
} else {
|
||||||
|
writer.response(400, "Access-Control-Allow-Origin: *");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,25 +1,24 @@
|
||||||
package dev.peerat.backend.routes;
|
package be.jeffcheasey88.peeratcode.routes;
|
||||||
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
import dev.peerat.backend.bonus.extract.RouteDoc;
|
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
|
||||||
import dev.peerat.backend.model.Completion;
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
import dev.peerat.backend.repository.DatabaseRepository;
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
import dev.peerat.framework.Context;
|
import be.jeffcheasey88.peeratcode.framework.Locker;
|
||||||
import dev.peerat.framework.HttpReader;
|
import be.jeffcheasey88.peeratcode.framework.Locker.Key;
|
||||||
import dev.peerat.framework.HttpWriter;
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
import dev.peerat.framework.Injection;
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
import dev.peerat.framework.Locker;
|
import be.jeffcheasey88.peeratcode.model.Completion;
|
||||||
import dev.peerat.framework.Locker.Key;
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
import dev.peerat.framework.Route;
|
|
||||||
|
|
||||||
public class DynamicLeaderboard extends Leaderboard{
|
public class DynamicLeaderboard extends Leaderboard{
|
||||||
|
|
||||||
private Locker<Completion> locker;
|
private Locker<Completion> locker;
|
||||||
|
|
||||||
public DynamicLeaderboard(DatabaseRepository databaseRepo, @Injection("leaderboard") Locker<Completion> locker){
|
public DynamicLeaderboard(DatabaseRepository databaseRepo){
|
||||||
super(databaseRepo);
|
super(databaseRepo);
|
||||||
this.locker = locker;
|
this.locker = new Locker<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Locker<Completion> getLocker(){
|
public Locker<Completion> getLocker(){
|
||||||
|
@ -29,7 +28,7 @@ public class DynamicLeaderboard extends Leaderboard{
|
||||||
@RouteDoc(path = "/rleaderboard/{id}", responseCode = 101, responseDescription = "WebSocket")
|
@RouteDoc(path = "/rleaderboard/{id}", responseCode = 101, responseDescription = "WebSocket")
|
||||||
|
|
||||||
@Route(path = "^\\/rleaderboard\\/?(\\d+)?$", websocket = true)
|
@Route(path = "^\\/rleaderboard\\/?(\\d+)?$", websocket = true)
|
||||||
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception{
|
||||||
Key key = new Key();
|
Key key = new Key();
|
||||||
|
|
||||||
locker.init(key);
|
locker.init(key);
|
92
src/be/jeffcheasey88/peeratcode/routes/Leaderboard.java
Normal file
92
src/be/jeffcheasey88/peeratcode/routes/Leaderboard.java
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.routes;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import org.json.simple.JSONArray;
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Chapter;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Group;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Player;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class Leaderboard implements Response {
|
||||||
|
|
||||||
|
private final DatabaseRepository databaseRepo;
|
||||||
|
|
||||||
|
public Leaderboard(DatabaseRepository databaseRepo) {
|
||||||
|
this.databaseRepo = databaseRepo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RouteDoc(path = "/leaderboard/{id}", responseCode = 200, responseDescription = "JSON contenant le leaderboard")
|
||||||
|
|
||||||
|
@Route(path = "^\\/leaderboard\\/?(\\d+)?$")
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *");
|
||||||
|
if (matcher.group(1) != null) {
|
||||||
|
groupsLeaderboard(Integer.parseInt(matcher.group(1)), writer);
|
||||||
|
} else {
|
||||||
|
playersLeaderboard(writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void groupsLeaderboard(int chapterId, HttpWriter writer) throws IOException {
|
||||||
|
Chapter chInfo = databaseRepo.getChapter(chapterId);
|
||||||
|
|
||||||
|
SortedSet<Group> allGroupsForChapter = databaseRepo.getAllGroupForChapterLeaderboard(chapterId);
|
||||||
|
JSONObject leaderboardJSON = new JSONObject();
|
||||||
|
if (chInfo.getStartDate() != null)
|
||||||
|
leaderboardJSON.put("start_date", chInfo.getStartDate().toString());
|
||||||
|
if (chInfo.getEndDate() != null)
|
||||||
|
leaderboardJSON.put("end_date", chInfo.getEndDate().toString());
|
||||||
|
JSONArray groupsJSON = new JSONArray();
|
||||||
|
if (allGroupsForChapter != null) {
|
||||||
|
int rank = 1;
|
||||||
|
int sameRankCount = 1;
|
||||||
|
Group previousGroup = null;
|
||||||
|
for (Group g : allGroupsForChapter) {
|
||||||
|
if (previousGroup != null) {
|
||||||
|
if (g.compareTo(previousGroup) == 0) {
|
||||||
|
sameRankCount++;
|
||||||
|
} else {
|
||||||
|
rank = rank + sameRankCount;
|
||||||
|
sameRankCount = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
groupsJSON.add(g.toJson(rank));
|
||||||
|
previousGroup = g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
leaderboardJSON.put("groups", groupsJSON);
|
||||||
|
writer.write(leaderboardJSON.toJSONString().replace("\\", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void playersLeaderboard(HttpWriter writer) throws IOException {
|
||||||
|
SortedSet<Player> allPlayers = databaseRepo.getAllPlayerForLeaderboard();
|
||||||
|
JSONArray playersJSON = new JSONArray();
|
||||||
|
if (allPlayers != null) {
|
||||||
|
for (Player player : allPlayers) {
|
||||||
|
JSONObject playerJSON = new JSONObject();
|
||||||
|
playerJSON.put("pseudo", player.getPseudo());
|
||||||
|
if (player.getGroups() != null)
|
||||||
|
playerJSON.put("groups", player.getJsonGroups());
|
||||||
|
// if (player.getAvatar() != null)
|
||||||
|
// playerJSON.put("avatar", Base64.getEncoder().encodeToString(player.getAvatar()));
|
||||||
|
playerJSON.put("rank", player.getRank());
|
||||||
|
playerJSON.put("score", player.getTotalScore());
|
||||||
|
playerJSON.put("completions", player.getTotalCompletion());
|
||||||
|
playerJSON.put("tries", player.getTotalTries());
|
||||||
|
playersJSON.add(playerJSON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.write(playersJSON.toJSONString().replace("\\", ""));
|
||||||
|
}
|
||||||
|
}
|
53
src/be/jeffcheasey88/peeratcode/routes/Login.java
Normal file
53
src/be/jeffcheasey88/peeratcode/routes/Login.java
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.routes;
|
||||||
|
|
||||||
|
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Router;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class Login implements Response {
|
||||||
|
|
||||||
|
private DatabaseRepository databaseRepo;
|
||||||
|
private Router router;
|
||||||
|
|
||||||
|
public Login(DatabaseRepository databaseRepo, Router router) {
|
||||||
|
this.databaseRepo = databaseRepo;
|
||||||
|
this.router = router;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RouteDoc(path = "/login", responseCode = 200, responseDescription = "L'utilisateur est inscrit")
|
||||||
|
@RouteDoc(responseCode = 403, responseDescription = "L'utilisateur est connecté")
|
||||||
|
@RouteDoc(responseCode = 400, responseDescription = "Aucune données fournie / données invalide")
|
||||||
|
|
||||||
|
@Route(path = "^\\/login$", type = POST)
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
|
||||||
|
if (user != null) {
|
||||||
|
writer.response(403, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JSONObject informations = reader.readJson();
|
||||||
|
if (informations != null) {
|
||||||
|
String pseudo = (String) informations.get("pseudo");
|
||||||
|
String password = (String) informations.get("passwd");
|
||||||
|
int id;
|
||||||
|
if ((id = databaseRepo.login(pseudo, password)) >= 0) {
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *",
|
||||||
|
"Access-Control-Expose-Headers: Authorization",
|
||||||
|
"Authorization: Bearer " + this.router.createAuthUser(id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.response(400, "Access-Control-Allow-Origin: *");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
61
src/be/jeffcheasey88/peeratcode/routes/PlayerDetails.java
Normal file
61
src/be/jeffcheasey88/peeratcode/routes/PlayerDetails.java
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.routes;
|
||||||
|
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Player;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class PlayerDetails implements Response {
|
||||||
|
|
||||||
|
private final DatabaseRepository databaseRepo;
|
||||||
|
|
||||||
|
public PlayerDetails(DatabaseRepository databaseRepo) {
|
||||||
|
this.databaseRepo = databaseRepo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RouteDoc(path = "/player/{id}", responseCode = 200, responseDescription = "JSON contenant les informations de l'utilisateur")
|
||||||
|
@RouteDoc(responseCode = 400, responseDescription = "Utilisateur introuvable dans la base de donnée")
|
||||||
|
|
||||||
|
@Route(path = "^\\/player\\/?(.+)?$", needLogin = true)
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
|
||||||
|
Player player;
|
||||||
|
if (matcher.group(1) != null) {
|
||||||
|
player = databaseRepo.getPlayerDetails(matcher.group(1));
|
||||||
|
} else {
|
||||||
|
player = databaseRepo.getPlayerDetails(user.getId());
|
||||||
|
}
|
||||||
|
JSONObject playerJSON = new JSONObject();
|
||||||
|
if (player != null) {
|
||||||
|
playerJSON.put("pseudo", player.getPseudo());
|
||||||
|
playerJSON.put("email", player.getEmail());
|
||||||
|
playerJSON.put("firstname", player.getFirstname());
|
||||||
|
playerJSON.put("lastname", player.getLastname());
|
||||||
|
playerJSON.put("description", player.getDescription());
|
||||||
|
if (player.getGroups() != null)
|
||||||
|
playerJSON.put("groups", player.getJsonGroups());
|
||||||
|
playerJSON.put("rank", player.getRank());
|
||||||
|
playerJSON.put("score", player.getTotalScore());
|
||||||
|
playerJSON.put("completions", player.getTotalCompletion());
|
||||||
|
playerJSON.put("completionsList", player.getJsonCompletions());
|
||||||
|
playerJSON.put("tries", player.getTotalTries());
|
||||||
|
if (player.getBadges() != null)
|
||||||
|
playerJSON.put("badges", player.getJsonBadges());
|
||||||
|
if (player.getAvatar() != null)
|
||||||
|
playerJSON.put("avatar", Base64.getEncoder().encodeToString(player.getAvatar()));
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *");
|
||||||
|
writer.write(playerJSON.toJSONString().replace("\\", ""));
|
||||||
|
} else {
|
||||||
|
writer.response(400, "Access-Control-Allow-Origin: *");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
72
src/be/jeffcheasey88/peeratcode/routes/PuzzleElement.java
Normal file
72
src/be/jeffcheasey88/peeratcode/routes/PuzzleElement.java
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.routes;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Chapter;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Completion;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Puzzle;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class PuzzleElement implements Response {
|
||||||
|
|
||||||
|
private final DatabaseRepository databaseRepo;
|
||||||
|
|
||||||
|
public PuzzleElement(DatabaseRepository databaseRepo) {
|
||||||
|
this.databaseRepo = databaseRepo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RouteDoc(path = "/puzzle/<id>", responseCode = 200, responseDescription = "JSON contenant les informations du puzzle")
|
||||||
|
@RouteDoc(responseCode = 400, responseDescription = "puzzle introuvable dans la base de donnée")
|
||||||
|
@RouteDoc(responseCode = 423, responseDescription = "L'utilisateur essaye de voir le puzzle en dehors de l'event")
|
||||||
|
|
||||||
|
@Route(path = "^\\/puzzle\\/([0-9]+)$", needLogin = true)
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
|
||||||
|
Puzzle puzzle = databaseRepo.getPuzzle(extractId(matcher));
|
||||||
|
if (puzzle != null){
|
||||||
|
Chapter chapter = this.databaseRepo.getChapter(puzzle);
|
||||||
|
if(chapter.getStartDate() != null){
|
||||||
|
if(LocalDateTime.now().isBefore(chapter.getStartDate().toLocalDateTime())){
|
||||||
|
writer.response(423, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if(chapter.getEndDate() != null){
|
||||||
|
// if(LocalDateTime.now().isAfter(chapter.getEndDate().toLocalDateTime())){
|
||||||
|
// writer.response(423, "Access-Control-Allow-Origin: *");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
JSONObject puzzleJSON = new JSONObject();
|
||||||
|
puzzleJSON.put("id", puzzle.getId());
|
||||||
|
puzzleJSON.put("name", puzzle.getName());
|
||||||
|
puzzleJSON.put("content", puzzle.getContent());
|
||||||
|
puzzleJSON.put("scoreMax", puzzle.getScoreMax());
|
||||||
|
if(puzzle.getTags() != null) puzzleJSON.put("tags", puzzle.getJsonTags());
|
||||||
|
Completion completion = this.databaseRepo.getCompletionGroup(user.getId(), puzzle.getId());
|
||||||
|
if(completion != null && completion.getScore() >= 0){
|
||||||
|
puzzleJSON.put("score", completion.getScore());
|
||||||
|
puzzleJSON.put("tries", completion.getTries());
|
||||||
|
}
|
||||||
|
if(puzzle.getDepend() > 0) puzzleJSON.put("depend", puzzle.getDepend());
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *", "Content-Type: application/json");
|
||||||
|
writer.write(puzzleJSON.toJSONString());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
writer.response(400, "Access-Control-Allow-Origin: *");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int extractId(Matcher matcher) {
|
||||||
|
return Integer.parseInt(matcher.group(1));
|
||||||
|
}
|
||||||
|
}
|
159
src/be/jeffcheasey88/peeratcode/routes/PuzzleResponse.java
Normal file
159
src/be/jeffcheasey88/peeratcode/routes/PuzzleResponse.java
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.routes;
|
||||||
|
|
||||||
|
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Locker;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Chapter;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Completion;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Group;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Player;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Puzzle;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class PuzzleResponse implements Response {
|
||||||
|
private final DatabaseRepository databaseRepo;
|
||||||
|
private final String usersFilesPath;
|
||||||
|
|
||||||
|
private final Locker<Completion> leaderboard;
|
||||||
|
|
||||||
|
public PuzzleResponse(DatabaseRepository databaseRepo, String initUsersFilesPath, Locker<Completion> locker){
|
||||||
|
this.databaseRepo = databaseRepo;
|
||||||
|
usersFilesPath = initUsersFilesPath;
|
||||||
|
this.leaderboard = locker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RouteDoc(path = "/puzzleResponse/<id>", responseCode = 200, responseDescription = "Bonne réponse, json contenant les points + tries")
|
||||||
|
@RouteDoc(responseCode = 400, responseDescription = "Pas de réponse")
|
||||||
|
@RouteDoc(responseCode = 403, responseDescription = "Déjà répondu")
|
||||||
|
@RouteDoc(responseCode = 406, responseDescription = "Mauvaise réponse")
|
||||||
|
@RouteDoc(responseCode = 423, responseDescription = "L'utilisateur essaye de répondre en dehors de l'event")
|
||||||
|
|
||||||
|
@Route(path = "^\\/puzzleResponse\\/([0-9]+)$", type = POST, needLogin = true)
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception{
|
||||||
|
ReceivedResponse received = new ReceivedResponse(matcher, reader);
|
||||||
|
if (received.getResponse() == null){
|
||||||
|
writer.response(400, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//saveSourceCode(received, databaseRepo.getPlayer(user.getId()));
|
||||||
|
JSONObject responseJSON = new JSONObject();
|
||||||
|
if(this.databaseRepo.getScore(user.getId(), received.getPuzzleId()) > 0){
|
||||||
|
writer.response(403, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Puzzle currentPuzzle = databaseRepo.getPuzzle(received.getPuzzleId());
|
||||||
|
Chapter chapter = this.databaseRepo.getChapter(currentPuzzle);
|
||||||
|
if(chapter.getStartDate() != null){
|
||||||
|
if(LocalDateTime.now().isBefore(chapter.getStartDate().toLocalDateTime())){
|
||||||
|
writer.response(423, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(chapter.getEndDate() != null){
|
||||||
|
if(LocalDateTime.now().isAfter(chapter.getEndDate().toLocalDateTime())){
|
||||||
|
if(Arrays.equals(currentPuzzle.getSoluce(), received.getResponse())){
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *", "Content-Type: application/json");
|
||||||
|
JSONObject theoSaisPasJusteRecevoir200 = new JSONObject();
|
||||||
|
theoSaisPasJusteRecevoir200.put("success", true);
|
||||||
|
writer.write(theoSaisPasJusteRecevoir200.toJSONString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
writer.response(423, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Group group = this.databaseRepo.getPlayerGroup(user.getId(), chapter.getId());
|
||||||
|
if(group == null){
|
||||||
|
writer.response(423, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Completion completion = databaseRepo.insertOrUpdatePuzzleResponse(received.getPuzzleId(), user.getId(),
|
||||||
|
received.getFileName(), received.getSourceCode(), received.getResponse(), currentPuzzle);
|
||||||
|
if(completion == null){
|
||||||
|
writer.response(400, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(completion.getScore() > 0){
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *", "Content-Type: application/json");
|
||||||
|
responseJSON.put("score", completion.getScore());
|
||||||
|
responseJSON.put("tries", completion.getTries());
|
||||||
|
|
||||||
|
}else{
|
||||||
|
writer.response(406, "Access-Control-Allow-Origin: *", "Content-Type: application/json");
|
||||||
|
responseJSON.put("tries", completion.getTries());
|
||||||
|
}
|
||||||
|
writer.write(responseJSON.toJSONString());
|
||||||
|
writer.flush();
|
||||||
|
|
||||||
|
leaderboard.setValue(completion);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveSourceCode(ReceivedResponse received, Player player){
|
||||||
|
try{
|
||||||
|
Path path = Paths.get(String.format("%s/%s/puz%04d-%s", usersFilesPath, player.getPseudo(),
|
||||||
|
received.getPuzzleId(), received.getFileName()));
|
||||||
|
Files.write(path, received.getSourceCode());
|
||||||
|
}catch (IOException e){
|
||||||
|
System.err.println("ERREUR D'ENREGISTREMENT DU CODE POUR PUZZLE_RESPONSE : " + e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReceivedResponse {
|
||||||
|
|
||||||
|
private int puzzleId;
|
||||||
|
private byte[] response;
|
||||||
|
private String fileName;
|
||||||
|
private byte[] sourceCode;
|
||||||
|
|
||||||
|
public ReceivedResponse(Matcher matcher, HttpReader reader) throws Exception {
|
||||||
|
puzzleId = Integer.parseInt(matcher.group(1));
|
||||||
|
|
||||||
|
List<String> multiPartData = reader.readMultiPartData();
|
||||||
|
if (multiPartData != null && multiPartData.size() > 0) {
|
||||||
|
this.response = multiPartData.get(0).getBytes();
|
||||||
|
if (multiPartData.size() == 3) {
|
||||||
|
this.fileName = multiPartData.get(1);
|
||||||
|
this.sourceCode = multiPartData.get(2).getBytes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPuzzleId() {
|
||||||
|
return puzzleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getResponse() {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getSourceCode() {
|
||||||
|
return sourceCode;
|
||||||
|
}
|
||||||
|
}
|
91
src/be/jeffcheasey88/peeratcode/routes/Register.java
Normal file
91
src/be/jeffcheasey88/peeratcode/routes/Register.java
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.routes;
|
||||||
|
|
||||||
|
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Router;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class Register implements Response {
|
||||||
|
|
||||||
|
private DatabaseRepository databaseRepo;
|
||||||
|
private Router router;
|
||||||
|
private String usersFilesPath;
|
||||||
|
|
||||||
|
public Register(DatabaseRepository databaseRepo, Router router, String initUsersFilesPath) {
|
||||||
|
this.databaseRepo = databaseRepo;
|
||||||
|
this.router = router;
|
||||||
|
usersFilesPath = initUsersFilesPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RouteDoc(path = "/register", responseCode = 200, responseDescription = "L'utilisateur est inscrit")
|
||||||
|
@RouteDoc(responseCode = 403, responseDescription = "L'utilisateur est connecté")
|
||||||
|
@RouteDoc(responseCode = 400, responseDescription = "Aucune données fournie / données invalide")
|
||||||
|
|
||||||
|
@Route(path = "^\\/register$", type = POST)
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception{
|
||||||
|
if (user != null){
|
||||||
|
writer.response(403, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JSONObject informations = reader.readJson();
|
||||||
|
if (informations != null) {
|
||||||
|
boolean allFieldsFilled = informations.containsKey("pseudo") && informations.containsKey("email")
|
||||||
|
&& informations.containsKey("passwd") && informations.containsKey("firstname")
|
||||||
|
&& informations.containsKey("lastname") && informations.containsKey("description")
|
||||||
|
&& informations.containsKey("sgroup") && informations.containsKey("avatar");
|
||||||
|
if (!allFieldsFilled) {
|
||||||
|
writer.response(403, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String pseudo = (String) informations.get("pseudo");
|
||||||
|
String email = (String) informations.get("email");
|
||||||
|
String password = (String) informations.get("passwd");
|
||||||
|
String firstname = (String) informations.get("firstname");
|
||||||
|
String lastname = (String) informations.get("lastname");
|
||||||
|
String description = (String) informations.get("description");
|
||||||
|
String group = (String) informations.get("sgroup");
|
||||||
|
String avatar = (String) informations.get("avatar");
|
||||||
|
|
||||||
|
boolean pseudoAvailable = databaseRepo.checkPseudoAvailability(pseudo);
|
||||||
|
boolean emailAvailable = databaseRepo.checkEmailAvailability(email);
|
||||||
|
if (pseudoAvailable && emailAvailable) {
|
||||||
|
int id;
|
||||||
|
if ((id = databaseRepo.register(pseudo, email, password, firstname, lastname, description, group,
|
||||||
|
avatar)) >= 0) {
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *",
|
||||||
|
"Access-Control-Expose-Headers: Authorization",
|
||||||
|
"Authorization: Bearer " + this.router.createAuthUser(id));
|
||||||
|
createFolderToSaveSourceCode(pseudo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
writer.response(400, "Access-Control-Allow-Origin: *");
|
||||||
|
JSONObject error = new JSONObject();
|
||||||
|
error.put("username_valid", pseudoAvailable);
|
||||||
|
error.put("email_valid", emailAvailable);
|
||||||
|
writer.write(error.toJSONString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.response(400, "Access-Control-Allow-Origin: *");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createFolderToSaveSourceCode(String pseudo) throws IOException {
|
||||||
|
|
||||||
|
Files.createDirectories(Paths.get(String.format("%s/%s", usersFilesPath, pseudo)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
37
src/be/jeffcheasey88/peeratcode/routes/Result.java
Normal file
37
src/be/jeffcheasey88/peeratcode/routes/Result.java
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.routes;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class Result implements Response {
|
||||||
|
|
||||||
|
private DatabaseRepository repo;
|
||||||
|
|
||||||
|
public Result(DatabaseRepository repo) {
|
||||||
|
this.repo = repo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RouteDoc(path = "/result/<id>", responseCode = 200, responseDescription = "Le score")
|
||||||
|
@RouteDoc(responseCode = 425, responseDescription = "Puzzle pas compléter")
|
||||||
|
|
||||||
|
@Route(path = "^\\/result\\/(\\d+)$", needLogin = true)
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
|
||||||
|
int puzzle = Integer.parseInt(matcher.group(1));
|
||||||
|
|
||||||
|
int score = this.repo.getScore(user.getId(), puzzle);
|
||||||
|
if (score < 0) {
|
||||||
|
writer.response(425, "Access-Control-Allow-Origin: *");
|
||||||
|
} else {
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *");
|
||||||
|
writer.write(score + "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.routes.groups;
|
||||||
|
|
||||||
|
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Locker;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Chapter;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Group;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class GroupCreate implements Response {
|
||||||
|
|
||||||
|
private Locker<Group> locker;
|
||||||
|
private DatabaseRepository repo;
|
||||||
|
private int groupDelay;
|
||||||
|
|
||||||
|
public GroupCreate(DatabaseRepository repo, Locker<Group> locker, int groupDelay){
|
||||||
|
this.repo = repo;
|
||||||
|
this.locker = locker;
|
||||||
|
this.groupDelay = groupDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RouteDoc(path = "/groupCreate", responseCode = 200, responseDescription = "Le groupe a été créé")
|
||||||
|
@RouteDoc(responseCode = 403, responseDescription = "L'utilisateur est déjà dans le groupe / ne peux pas le rejoindre")
|
||||||
|
@RouteDoc(responseCode = 423, responseDescription = "L'utilisateur essaye de crée un groupe après le délai maximum de création de l'event")
|
||||||
|
|
||||||
|
@Route(path = "^\\/groupCreate$", type = POST, needLogin = true)
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception{
|
||||||
|
Group newGroup = new Group(reader.readJson());
|
||||||
|
|
||||||
|
if (this.repo.getPlayerGroup(user.getId(), newGroup.getLinkToChapter()) == null) {
|
||||||
|
try {
|
||||||
|
if(this.repo.getGroupId(newGroup) == null) throw new NullPointerException();
|
||||||
|
writer.response(403, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}catch(NullPointerException e){
|
||||||
|
if(newGroup.getLinkToChapter() != null){
|
||||||
|
Chapter chapter = this.repo.getChapter(newGroup.getLinkToChapter());
|
||||||
|
if(chapter.getStartDate() != null){
|
||||||
|
LocalDateTime start = chapter.getStartDate().toLocalDateTime().plusMinutes(this.groupDelay);
|
||||||
|
if(LocalDateTime.now().isAfter(start)){
|
||||||
|
writer.response(423, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.repo.insertGroup(newGroup, user)) {
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *");
|
||||||
|
|
||||||
|
locker.setValue(newGroup);
|
||||||
|
} else {
|
||||||
|
writer.response(403, "Access-Control-Allow-Origin: *");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
writer.response(403, "Access-Control-Allow-Origin: *");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
76
src/be/jeffcheasey88/peeratcode/routes/groups/GroupJoin.java
Normal file
76
src/be/jeffcheasey88/peeratcode/routes/groups/GroupJoin.java
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.routes.groups;
|
||||||
|
|
||||||
|
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Locker;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Chapter;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Completion;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Group;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class GroupJoin implements Response{
|
||||||
|
|
||||||
|
private DatabaseRepository repo;
|
||||||
|
private int groupDelay;
|
||||||
|
private String waitTime;
|
||||||
|
|
||||||
|
private final Locker<Completion> leaderboard;
|
||||||
|
|
||||||
|
public GroupJoin(DatabaseRepository repo, int groupDelay, String waitTime, Locker<Completion> locker){
|
||||||
|
this.repo = repo;
|
||||||
|
this.groupDelay = groupDelay;
|
||||||
|
this.waitTime = waitTime;
|
||||||
|
this.leaderboard = locker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RouteDoc(path = "/groupJoin", responseCode = 200, responseDescription = "L'utilisateur a rejoint le groupe")
|
||||||
|
@RouteDoc(responseCode = 403, responseDescription = "L'utilisateur est déjà dedans / ne peux pas le rejoindre")
|
||||||
|
@RouteDoc(responseCode = 423, responseDescription = "L'utilisateur essaye de rejoindre un groupe après le délai maximum de création de l'event")
|
||||||
|
@RouteDoc(responseCode = 409, responseDescription = "L'utilisateur est un peu débile... ou pas ?")
|
||||||
|
|
||||||
|
@Route(path = "^\\/groupJoin$", type = POST, needLogin = true)
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception{
|
||||||
|
Group group = new Group(reader.readJson());
|
||||||
|
|
||||||
|
Group userGroup = this.repo.getPlayerGroup(user.getId(), group.getLinkToChapter());
|
||||||
|
if(group.equals(userGroup)){
|
||||||
|
writer.response(403, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(group.getLinkToChapter() == null){
|
||||||
|
writer.response(409, "Access-Control-Allow-Origin: *");
|
||||||
|
writer.write(waitTime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(group.getLinkToChapter() != null){
|
||||||
|
Chapter chapter = this.repo.getChapter(group.getLinkToChapter());
|
||||||
|
if(chapter.getStartDate() != null){
|
||||||
|
LocalDateTime start = chapter.getStartDate().toLocalDateTime().plusMinutes(this.groupDelay);
|
||||||
|
if(LocalDateTime.now().isAfter(start)){
|
||||||
|
writer.response(423, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.repo.insertUserInGroup(group, user)) {
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *");
|
||||||
|
|
||||||
|
leaderboard.setValue(new Completion(0, 0, 0, null, 0));
|
||||||
|
} else {
|
||||||
|
writer.response(403, "Access-Control-Allow-Origin: *");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
34
src/be/jeffcheasey88/peeratcode/routes/groups/GroupList.java
Normal file
34
src/be/jeffcheasey88/peeratcode/routes/groups/GroupList.java
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.routes.groups;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import org.json.simple.JSONArray;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Group;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class GroupList implements Response {
|
||||||
|
|
||||||
|
private DatabaseRepository repo;
|
||||||
|
|
||||||
|
public GroupList(DatabaseRepository repo) {
|
||||||
|
this.repo = repo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RouteDoc(path = "/groups", responseCode = 200, responseDescription = "JSON avec la liste des groups")
|
||||||
|
|
||||||
|
@Route(path = "^\\/groups$", needLogin = true)
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *");
|
||||||
|
JSONArray result = new JSONArray();
|
||||||
|
for(Group group : this.repo.getAllGroups()) result.add(group.toJson());
|
||||||
|
writer.write(result.toJSONString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
68
src/be/jeffcheasey88/peeratcode/routes/groups/GroupQuit.java
Normal file
68
src/be/jeffcheasey88/peeratcode/routes/groups/GroupQuit.java
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.routes.groups;
|
||||||
|
|
||||||
|
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpReader;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Locker;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.Route;
|
||||||
|
import be.jeffcheasey88.peeratcode.framework.User;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Chapter;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Completion;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Group;
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
|
public class GroupQuit implements Response{
|
||||||
|
|
||||||
|
private DatabaseRepository repo;
|
||||||
|
private int groupDelay;
|
||||||
|
|
||||||
|
private final Locker<Completion> leaderboard;
|
||||||
|
|
||||||
|
public GroupQuit(DatabaseRepository repo, int groupDelay, Locker<Completion> locker){
|
||||||
|
this.repo = repo;
|
||||||
|
this.groupDelay = groupDelay;
|
||||||
|
|
||||||
|
this.leaderboard = locker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RouteDoc(path = "/groupQuit", responseCode = 200, responseDescription = "L'utilisateur à quitter le groupe")
|
||||||
|
@RouteDoc(responseCode = 403, responseDescription = "L'utilisateur n'est pas dans le groupe / n'a pas pu le quittez")
|
||||||
|
@RouteDoc(responseCode = 423, responseDescription = "L'utilisateur essaye de quitter un groupe après le délai maximum de création de l'event")
|
||||||
|
|
||||||
|
@Route(path = "^\\/groupQuit$", type = POST, needLogin = true)
|
||||||
|
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception{
|
||||||
|
Group group = new Group(reader.readJson());
|
||||||
|
|
||||||
|
Group userGroup = this.repo.getPlayerGroup(user.getId(), group.getLinkToChapter());
|
||||||
|
if(!group.equals(userGroup)){
|
||||||
|
writer.response(403, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(group.getLinkToChapter() != null){
|
||||||
|
Chapter chapter = this.repo.getChapter(group.getLinkToChapter());
|
||||||
|
if(chapter.getStartDate() != null){
|
||||||
|
LocalDateTime start = chapter.getStartDate().toLocalDateTime().plusMinutes(this.groupDelay);
|
||||||
|
if(LocalDateTime.now().isAfter(start)){
|
||||||
|
writer.response(423, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.repo.leaveGroup(group, user)) {
|
||||||
|
writer.response(200, "Access-Control-Allow-Origin: *");
|
||||||
|
|
||||||
|
leaderboard.setValue(new Completion(0, 0, 0, null, 0));
|
||||||
|
} else {
|
||||||
|
writer.response(403, "Access-Control-Allow-Origin: *");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,184 +0,0 @@
|
||||||
package dev.peerat.backend;
|
|
||||||
|
|
||||||
import static dev.peerat.framework.RequestType.OPTIONS;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
|
|
||||||
import dev.peerat.backend.bonus.extract.RouteExtracter;
|
|
||||||
import dev.peerat.backend.model.Group;
|
|
||||||
import dev.peerat.backend.model.PeerAtUser;
|
|
||||||
import dev.peerat.backend.repository.ConnectionManager;
|
|
||||||
import dev.peerat.backend.repository.DatabaseRepository;
|
|
||||||
import dev.peerat.framework.Context;
|
|
||||||
import dev.peerat.framework.DependencyInjector;
|
|
||||||
import dev.peerat.framework.HttpReader;
|
|
||||||
import dev.peerat.framework.HttpWriter;
|
|
||||||
import dev.peerat.framework.Locker;
|
|
||||||
import dev.peerat.framework.Locker.Key;
|
|
||||||
import dev.peerat.framework.RequestType;
|
|
||||||
import dev.peerat.framework.Response;
|
|
||||||
import dev.peerat.framework.Route;
|
|
||||||
import dev.peerat.framework.RouteInterceptor;
|
|
||||||
import dev.peerat.framework.Router;
|
|
||||||
import dev.peerat.framework.auth.Authenticator;
|
|
||||||
import dev.peerat.framework.auth.JwtAuthenticator;
|
|
||||||
import dev.peerat.framework.utils.json.JsonMap;
|
|
||||||
import dev.peerat.framework.utils.json.JsonParser;
|
|
||||||
|
|
||||||
public class Main{
|
|
||||||
|
|
||||||
private static Router<PeerAtUser> ACCESS_ROUTER;
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception{
|
|
||||||
Configuration config = new Configuration("config.txt").addDefaultValue("users_files", "/tmp/users_files");
|
|
||||||
config.load();
|
|
||||||
|
|
||||||
Class.forName("com.mysql.cj.jdbc.Driver");
|
|
||||||
|
|
||||||
DatabaseRepository repo = new DatabaseRepository(new ConnectionManager(config), config);
|
|
||||||
Router<PeerAtUser> router = new Router<PeerAtUser>()
|
|
||||||
.activeReOrdering().
|
|
||||||
addDefaultHeaders(RequestType.GET, "Access-Control-Allow-Origin: *").
|
|
||||||
addDefaultHeaders(RequestType.POST, "Access-Control-Allow-Origin: *").
|
|
||||||
addDefaultHeaders(RequestType.OPTIONS,
|
|
||||||
"Access-Control-Allow-Origin: *",
|
|
||||||
"Access-Control-Allow-Methods: *",
|
|
||||||
"Access-Control-Allow-Headers: *");
|
|
||||||
ACCESS_ROUTER = router;
|
|
||||||
|
|
||||||
Authenticator<PeerAtUser> auth;
|
|
||||||
if(config.getJwtKey() != null){
|
|
||||||
JsonParser parser = new JsonParser();
|
|
||||||
JsonMap json = parser.parse(config.getJwtKey());
|
|
||||||
Map<String, Object> params = new HashMap<>();
|
|
||||||
for(Entry<String, Object> entry : json.entries()) params.put(entry.getKey(), entry.getValue());
|
|
||||||
auth = new JwtAuthenticator<PeerAtUser>().configure(
|
|
||||||
(builder) -> builder.setExpectedIssuer(config.getTokenIssuer()),
|
|
||||||
(claims) -> {
|
|
||||||
claims.setIssuer(config.getTokenIssuer());
|
|
||||||
claims.setExpirationTimeMinutesInTheFuture(config.getTokenExpiration());
|
|
||||||
},
|
|
||||||
(claims) -> new PeerAtUser(claims),
|
|
||||||
params);
|
|
||||||
}else{
|
|
||||||
auth = new JwtAuthenticator<PeerAtUser>().configure(
|
|
||||||
(builder) -> builder.setExpectedIssuer(config.getTokenIssuer()),
|
|
||||||
(claims) -> {
|
|
||||||
claims.setIssuer(config.getTokenIssuer());
|
|
||||||
claims.setExpirationTimeMinutesInTheFuture(config.getTokenExpiration());
|
|
||||||
},
|
|
||||||
(claims) -> new PeerAtUser(claims));
|
|
||||||
JsonMap json = new JsonMap();
|
|
||||||
for(Entry<String, Object> entry : ((JwtAuthenticator<PeerAtUser>)auth).exportKey().entrySet()){
|
|
||||||
json.set(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
config.setJwtKey(json.toString());
|
|
||||||
config.save();
|
|
||||||
}
|
|
||||||
router.setAuthenticator(auth);
|
|
||||||
|
|
||||||
router.setDefault((matcher, context, reader, writer) -> {
|
|
||||||
context.response(404);
|
|
||||||
writer.write("404 not Found.\n");
|
|
||||||
});
|
|
||||||
|
|
||||||
router.register(new Response(){
|
|
||||||
@Route(path = "^(.*)$", type = OPTIONS)
|
|
||||||
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
|
|
||||||
context.response(200);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
initRoutes(router, repo, config);
|
|
||||||
|
|
||||||
router.addInterceptor(new RouteInterceptor(){
|
|
||||||
@Override
|
|
||||||
public boolean intercept(Matcher matcher, Context context, HttpReader reader, HttpWriter writer, Method method){
|
|
||||||
if(method.getDeclaringClass().getPackage().getName().contains(".admins")){
|
|
||||||
try {
|
|
||||||
Group group = repo.getGroupRepository().getPlayerGroup(context.<PeerAtUser>getUser().getId(), 1);
|
|
||||||
if(!group.getName().equalsIgnoreCase("Quarter-Master - Battles PAC x CEI")){
|
|
||||||
context.response(401);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}catch(Exception ex){
|
|
||||||
ex.printStackTrace();
|
|
||||||
try{
|
|
||||||
context.response(401);
|
|
||||||
}catch(Exception e){}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
new Thread(new Runnable(){
|
|
||||||
public void run(){
|
|
||||||
Key key = new Key();
|
|
||||||
|
|
||||||
Locker<Context> locker = router.getLogger();
|
|
||||||
|
|
||||||
locker.init(key);
|
|
||||||
try {
|
|
||||||
while(true){
|
|
||||||
locker.lock(key);
|
|
||||||
Context instance = locker.getValue(key);
|
|
||||||
if(instance == null) continue;
|
|
||||||
System.out.println("["+((instance.isLogged()) ? repo.getPlayerRepository().getPlayer(instance.<PeerAtUser>getUser().getId()).getPseudo() : "?")+"] "+instance.getType()+" "+instance.getPath()+" -> "+instance.getResponseCode());
|
|
||||||
}
|
|
||||||
}catch(Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
locker.remove(key);
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
|
|
||||||
new Thread(new Runnable(){
|
|
||||||
public void run(){
|
|
||||||
Key key = new Key();
|
|
||||||
|
|
||||||
Locker<Throwable> locker = router.getExceptionLogger();
|
|
||||||
|
|
||||||
locker.init(key);
|
|
||||||
try {
|
|
||||||
while(true){
|
|
||||||
locker.lock(key);
|
|
||||||
locker.getValue(key).printStackTrace();
|
|
||||||
}
|
|
||||||
}catch(Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
locker.remove(key);
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
|
|
||||||
if(config.useSsl()) router.configureSSL(config.getSslKeystore(), config.getSslKeystorePasswd());
|
|
||||||
router.listen(config.getTcpPort(), config.useSsl());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void initRoutes(Router<PeerAtUser> router, DatabaseRepository repo, Configuration config) throws Exception{
|
|
||||||
Predicate<PeerAtUser> isAdmin = (user) -> {
|
|
||||||
try {
|
|
||||||
Group group = repo.getGroupRepository().getPlayerGroup(user.getId(), 1);
|
|
||||||
return group.getName().equalsIgnoreCase("Quarter-Master - Battles PAC x CEI");
|
|
||||||
}catch(Exception ex){}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
router.registerPackages("dev.peerat.backend.routes",new DependencyInjector()
|
|
||||||
.of(repo, router, config, new RouteExtracter(router), config.getMail(), isAdmin)
|
|
||||||
.of("waitting", new HashMap<>())
|
|
||||||
.of("leaderboard", new Locker<>())
|
|
||||||
.of("groups", new Locker<>())
|
|
||||||
.of("groupMessages", new Locker<>()));
|
|
||||||
|
|
||||||
// Bot bot = new Bot(config, repo, groupLock);
|
|
||||||
// bot.start();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,131 +0,0 @@
|
||||||
package dev.peerat.backend.bonus.extract;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import dev.peerat.backend.model.PeerAtUser;
|
|
||||||
import dev.peerat.framework.RequestType;
|
|
||||||
import dev.peerat.framework.Response;
|
|
||||||
import dev.peerat.framework.Route;
|
|
||||||
import dev.peerat.framework.RouteMapper;
|
|
||||||
import dev.peerat.framework.Router;
|
|
||||||
import dev.peerat.framework.utils.json.JsonArray;
|
|
||||||
import dev.peerat.framework.utils.json.JsonMap;
|
|
||||||
|
|
||||||
public class RouteExtracter {
|
|
||||||
|
|
||||||
private Router<PeerAtUser> router;
|
|
||||||
|
|
||||||
public RouteExtracter(Router<PeerAtUser> router){
|
|
||||||
this.router = router;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void extract() throws Exception{
|
|
||||||
RouteMapper[] mappers = getField(Router.class, router, "mappers");
|
|
||||||
for(RequestType type : RequestType.values()){
|
|
||||||
RouteMapper mapper = mappers[type.ordinal()];
|
|
||||||
Response[] responses = getField(RouteMapper.class, mapper, "responses");
|
|
||||||
Route[] routes = getField(RouteMapper.class, mapper, "routes");
|
|
||||||
synchronized (responses){
|
|
||||||
for(int i = 0; i < responses.length; i++){
|
|
||||||
Route route = routes[i];
|
|
||||||
System.out.println("["+type+"] ("+route.needLogin()+") "+route.path());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void extractDoc() throws Exception{
|
|
||||||
RouteMapper[] mappers = getField(Router.class, router, "mappers");
|
|
||||||
for(RequestType type : RequestType.values()){
|
|
||||||
RouteMapper mapper = mappers[type.ordinal()];
|
|
||||||
Response[] responses = getField(RouteMapper.class, mapper, "responses");
|
|
||||||
synchronized (responses){
|
|
||||||
for(int i = 0; i < responses.length; i++){
|
|
||||||
Response response = responses[i];
|
|
||||||
Method method = response.getClass().getDeclaredMethod("exec",
|
|
||||||
Response.class.getDeclaredMethods()[0].getParameterTypes());
|
|
||||||
for(RouteDoc doc : method.getDeclaredAnnotationsByType(RouteDoc.class)){
|
|
||||||
System.out.println(doc.path()+((doc.path().isEmpty() ? "":"\n"))+" ["+doc.responseCode()+"] "+doc.responseDescription());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonMap swagger(String host) throws Exception{
|
|
||||||
JsonMap result = new JsonMap();
|
|
||||||
result.set("swagger","2.0");
|
|
||||||
JsonMap info = new JsonMap();
|
|
||||||
info.set("title", "Peer-at-code backend api routes");
|
|
||||||
info.set("description", "Using Peer-at Code Framework");
|
|
||||||
result.set("info", info);
|
|
||||||
result.set("host", host);
|
|
||||||
result.set("basePath","/");
|
|
||||||
|
|
||||||
List<Response> routes = new ArrayList<>();
|
|
||||||
RouteMapper[] mappers = getField(Router.class, router, "mappers");
|
|
||||||
for(RequestType type : RequestType.values()){
|
|
||||||
RouteMapper mapper = mappers[type.ordinal()];
|
|
||||||
Response[] responses = getField(RouteMapper.class, mapper, "responses");
|
|
||||||
synchronized (responses){
|
|
||||||
routes.addAll(Arrays.asList(responses));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<String> packages = new HashSet<>();
|
|
||||||
for(Response response : routes){
|
|
||||||
String name = response.getClass().getPackage().getName();
|
|
||||||
name = name.substring(name.lastIndexOf('.')+1, name.length());
|
|
||||||
packages.add(name);
|
|
||||||
}
|
|
||||||
JsonArray tags = new JsonArray();
|
|
||||||
for(String tag : packages){
|
|
||||||
JsonMap current = new JsonMap();
|
|
||||||
current.set("name", tag);
|
|
||||||
tags.add(current);
|
|
||||||
}
|
|
||||||
result.set("tags", tags);
|
|
||||||
JsonArray schemes = new JsonArray();
|
|
||||||
schemes.add("https");
|
|
||||||
result.set("schemes", schemes);
|
|
||||||
|
|
||||||
JsonMap paths = new JsonMap();
|
|
||||||
|
|
||||||
for(Response response : routes){
|
|
||||||
Method method = response.getClass().getDeclaredMethod("exec",
|
|
||||||
Response.class.getDeclaredMethods()[0].getParameterTypes());
|
|
||||||
Route route = method.getDeclaredAnnotation(Route.class);
|
|
||||||
RouteDoc[] docs = method.getDeclaredAnnotationsByType(RouteDoc.class);
|
|
||||||
if(docs.length < 1) continue;
|
|
||||||
RouteDoc base = docs[0];
|
|
||||||
JsonMap current = new JsonMap();
|
|
||||||
JsonMap data = new JsonMap();
|
|
||||||
JsonArray tag = new JsonArray();
|
|
||||||
String pack = response.getClass().getPackage().getName();
|
|
||||||
pack = pack.substring(pack.lastIndexOf('.')+1, pack.length());
|
|
||||||
tag.add(pack);
|
|
||||||
data.set("tags", tag);
|
|
||||||
|
|
||||||
|
|
||||||
current.set(route.type().toString().toLowerCase(), data);
|
|
||||||
|
|
||||||
paths.set(base.path(), current);
|
|
||||||
}
|
|
||||||
|
|
||||||
result.set("paths", paths);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private <E> E getField(Class<?> clazz, Object instance, String name) throws Exception{
|
|
||||||
Field field = clazz.getDeclaredField(name);
|
|
||||||
field.setAccessible(true);
|
|
||||||
return (E) field.get(instance);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package dev.peerat.backend.model;
|
|
||||||
|
|
||||||
import org.jose4j.jwt.JwtClaims;
|
|
||||||
|
|
||||||
public class PeerAtUser extends dev.peerat.framework.User{
|
|
||||||
|
|
||||||
private int id;
|
|
||||||
|
|
||||||
public PeerAtUser(int id){
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PeerAtUser(JwtClaims claims){
|
|
||||||
this.id = ((Long) claims.getClaimValue("id")).intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(JwtClaims claims){
|
|
||||||
claims.setClaim("id", this.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId(){
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
package dev.peerat.backend.model;
|
|
||||||
|
|
||||||
import dev.peerat.framework.utils.json.JsonMap;
|
|
||||||
|
|
||||||
public class Tag{
|
|
||||||
|
|
||||||
private int id;
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
public Tag(int id, String name){
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId(){
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName(){
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonMap toJson(){
|
|
||||||
JsonMap result = new JsonMap();
|
|
||||||
result.set("id", id);
|
|
||||||
result.set("name", name);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,114 +0,0 @@
|
||||||
package dev.peerat.backend.repository;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.ResultSetMetaData;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
import dev.peerat.backend.Configuration;
|
|
||||||
import dev.peerat.backend.model.Badge;
|
|
||||||
import dev.peerat.backend.model.Chapter;
|
|
||||||
import dev.peerat.backend.model.Completion;
|
|
||||||
import dev.peerat.backend.model.Group;
|
|
||||||
import dev.peerat.backend.model.Player;
|
|
||||||
import dev.peerat.backend.model.Puzzle;
|
|
||||||
|
|
||||||
public class BaseDatabaseQuery{
|
|
||||||
|
|
||||||
private ConnectionManager con;
|
|
||||||
private Configuration config;
|
|
||||||
|
|
||||||
public BaseDatabaseQuery(ConnectionManager con){
|
|
||||||
this.con = con;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Connection ensureConnection() throws SQLException{
|
|
||||||
return this.con.ensureConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepare(String request) throws SQLException{
|
|
||||||
return this.con.ensureConnection().prepareStatement(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Puzzle makePuzzle(ResultSet puzzleResult) throws SQLException {
|
|
||||||
return new Puzzle(puzzleResult.getInt("id_puzzle"), puzzleResult.getString("name"),
|
|
||||||
puzzleResult.getString("content"), puzzleResult.getBytes("soluce"), puzzleResult.getString("verify"),
|
|
||||||
puzzleResult.getInt("score_max"), puzzleResult.getString("tags"),
|
|
||||||
hasColumn(puzzleResult, "origin") ? puzzleResult.getInt("origin") : -1,
|
|
||||||
puzzleResult.getTimestamp("start_date"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Chapter makeChapter(ResultSet chapterResult) throws SQLException {
|
|
||||||
return new Chapter(chapterResult.getInt("id_chapter"), chapterResult.getString("name"),
|
|
||||||
chapterResult.getTimestamp("start_date"), chapterResult.getTimestamp("end_date"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Completion makeCompletion(ResultSet completionResult) throws SQLException {
|
|
||||||
String fileName = null;
|
|
||||||
if (hasColumn(completionResult, "fileName"))
|
|
||||||
fileName = completionResult.getString("fileName");
|
|
||||||
String puzzleName = null;
|
|
||||||
if (hasColumn(completionResult, "name"))
|
|
||||||
puzzleName = completionResult.getString("name");
|
|
||||||
|
|
||||||
return new Completion(completionResult.getInt("fk_player"), completionResult.getInt("fk_puzzle"), completionResult.getInt("tries"),
|
|
||||||
fileName, completionResult.getInt("score"), puzzleName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Player makePlayer(ResultSet playerResult, int id) throws SQLException {
|
|
||||||
Player p = new Player(playerResult.getString("pseudo"), playerResult.getString("email"),
|
|
||||||
playerResult.getString("firstName"), playerResult.getString("lastName"));
|
|
||||||
if (hasColumn(playerResult, "avatar")) {
|
|
||||||
p.setAvatar(playerResult.getBytes("avatar"));
|
|
||||||
}
|
|
||||||
if (hasColumn(playerResult, "score")) {
|
|
||||||
p.addCompletion(new Completion(playerResult.getInt("tries"), playerResult.getInt("score")));
|
|
||||||
for (int ct = 1; ct < playerResult.getInt("completions"); ct++)
|
|
||||||
{ // TODO refactor for V3
|
|
||||||
p.addCompletion(new Completion(0, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hasColumn(playerResult, "name")) {
|
|
||||||
// Manage groups
|
|
||||||
String groupName = playerResult.getString("name");
|
|
||||||
if (groupName != null) {
|
|
||||||
p.addGroup(makeGroup(playerResult));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ADD rank
|
|
||||||
PreparedStatement completionsStmt = con.ensureConnection().prepareStatement(DatabasePlayerRepository.GET_PLAYER_RANK());
|
|
||||||
completionsStmt.setInt(1, id);
|
|
||||||
ResultSet result = completionsStmt.executeQuery();
|
|
||||||
while (result.next()) {
|
|
||||||
p.setRank(result.getInt("rank"));
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Group makeGroup(ResultSet result) throws SQLException {
|
|
||||||
return new Group(result.getString("name"), result.getInt("fk_chapter"), result.getInt("fk_puzzle"), ((hasColumn(result, "countPlayer")) ? result.getInt("countPlayer") : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Player makeGroupPlayer(ResultSet result) throws SQLException {
|
|
||||||
return new Player(result.getString("pseudo"), result.getInt("score"), result.getInt("tries"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Badge makeBadge(ResultSet rs) throws SQLException {
|
|
||||||
return new Badge(rs.getString("name"), rs.getBytes("logo"), rs.getInt("level"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasColumn(ResultSet rs, String columnName) throws SQLException {
|
|
||||||
// Found on StackOverflow
|
|
||||||
ResultSetMetaData rsmd = rs.getMetaData();
|
|
||||||
int columns = rsmd.getColumnCount();
|
|
||||||
for (int x = 1; x <= columns; x++) {
|
|
||||||
if (columnName.equals(rsmd.getColumnName(x)))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package dev.peerat.backend.repository;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
import dev.peerat.backend.Configuration;
|
|
||||||
|
|
||||||
public class ConnectionManager {
|
|
||||||
|
|
||||||
private Connection con;
|
|
||||||
private Configuration config;
|
|
||||||
|
|
||||||
public ConnectionManager(Configuration config){
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Connection ensureConnection() throws SQLException {
|
|
||||||
if (con == null || (!con.isValid(5))) {
|
|
||||||
this.con = DriverManager.getConnection(
|
|
||||||
"jdbc:mysql://" + config.getDbHost() + ":" + config.getDbPort() + "/" + config.getDbDatabase() + "",
|
|
||||||
config.getDbUser(), config.getDbPassword());
|
|
||||||
}
|
|
||||||
return this.con;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,194 +0,0 @@
|
||||||
package dev.peerat.backend.repository;
|
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import dev.peerat.backend.Configuration;
|
|
||||||
import dev.peerat.backend.model.Chapter;
|
|
||||||
import dev.peerat.backend.model.Puzzle;
|
|
||||||
import dev.peerat.backend.model.Tag;
|
|
||||||
|
|
||||||
public class DatabaseAdminRepository extends BaseDatabaseQuery{
|
|
||||||
|
|
||||||
private static enum Query{
|
|
||||||
|
|
||||||
//ADMIN
|
|
||||||
ADD_CHAPTER("INSERT INTO chapters (name, start_date, end_date) VALUES (?,?,?)"),
|
|
||||||
DELETE_CHAPTER("DELETE FROM chapters WHERE id_chapter = ?"),
|
|
||||||
EDIT_CHAPTER("UPDATE chapters SET name = ?, start_date = ?, end_date = ? WHERE id_chapter = ?"),
|
|
||||||
GET_CHAPTER("SELECT * FROM chapters WHERE id_chapter = ?"),
|
|
||||||
|
|
||||||
ADD_PUZZLE("INSERT INTO puzzles (name, content, soluce, verify, score_max, fk_chapter) VALUES (?,?,?,?,?,?)"),
|
|
||||||
DELETE_PUZZLE("DELETE FROM puzzles WHERE id_puzzle = ?"),
|
|
||||||
EDIT_PUZZLE("UPDATE puzzles SET name = ?, content = ?, soluce = ?, verify = ?, score_max = ?, fk_chapter = ? WHERE id_puzzle = ?"),
|
|
||||||
GET_PUZZLE("SELECT p.*, GROUP_CONCAT(t.name) AS tags FROM puzzles p LEFT JOIN containsTags ct ON ct.fk_puzzle = p.id_puzzle LEFT JOIN tags t ON t.id_tag = ct.fk_tag WHERE p.id_puzzle = ? GROUP BY p.id_puzzle"),
|
|
||||||
GET_PUZZLES("SELECT p.*, GROUP_CONCAT(t.name) AS tags FROM puzzles p LEFT JOIN containsTags ct ON ct.fk_puzzle = p.id_puzzle LEFT JOIN tags t ON t.id_tag = ct.fk_tag GROUP BY p.id_puzzle"),
|
|
||||||
|
|
||||||
ADD_TAG("INSERT INTO tags (name) VALUES (?)"),
|
|
||||||
DELETE_TAG("DELETE FROM tags WHERE id_tag = ?"),
|
|
||||||
EDIT_TAG("UPDATE tags SET name = ? WHERE id_tag = ?"),
|
|
||||||
GET_TAGS("SELECT * FROM tags");
|
|
||||||
|
|
||||||
private String request;
|
|
||||||
|
|
||||||
Query(Query parent, String request) {
|
|
||||||
this.request = parent.request + request;
|
|
||||||
}
|
|
||||||
|
|
||||||
Query(String request) {
|
|
||||||
this.request = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
|
|
||||||
return base.prepare(this.request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.request;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Configuration config;
|
|
||||||
|
|
||||||
public DatabaseAdminRepository(ConnectionManager con, Configuration config){
|
|
||||||
super(con);
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
//ADMIN
|
|
||||||
public Chapter getAdminChapter(int id){
|
|
||||||
try {
|
|
||||||
PreparedStatement chapterStmt = Query.GET_CHAPTER.prepare(this);
|
|
||||||
chapterStmt.setInt(1, id);
|
|
||||||
ResultSet chapterResult = chapterStmt.executeQuery();
|
|
||||||
if (chapterResult.next()) {
|
|
||||||
Chapter chapter = makeChapter(chapterResult);
|
|
||||||
return chapter;
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Puzzle getAdminPuzzle(int id){
|
|
||||||
try {
|
|
||||||
PreparedStatement chapterStmt = Query.GET_PUZZLE.prepare(this);
|
|
||||||
chapterStmt.setInt(1, id);
|
|
||||||
ResultSet chapterResult = chapterStmt.executeQuery();
|
|
||||||
if (chapterResult.next()) {
|
|
||||||
return makePuzzle(chapterResult);
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Puzzle> getAdminPuzzles(){
|
|
||||||
try {
|
|
||||||
PreparedStatement chapterStmt = Query.GET_PUZZLES.prepare(this);
|
|
||||||
ResultSet chapterResult = chapterStmt.executeQuery();
|
|
||||||
List<Puzzle> list = new ArrayList<>();
|
|
||||||
while(chapterResult.next()){
|
|
||||||
list.add(makePuzzle(chapterResult));
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Tag> getAdminTags(){
|
|
||||||
try {
|
|
||||||
PreparedStatement chapterStmt = Query.GET_TAGS.prepare(this);
|
|
||||||
ResultSet chapterResult = chapterStmt.executeQuery();
|
|
||||||
List<Tag> list = new ArrayList<>();
|
|
||||||
while(chapterResult.next()){
|
|
||||||
list.add(new Tag(chapterResult.getInt("id_tag"), chapterResult.getString("name")));
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean adminAddChapter(Chapter chapter) throws SQLException {
|
|
||||||
PreparedStatement statement = Query.ADD_CHAPTER.prepare(this);
|
|
||||||
statement.setString(1, chapter.getName());
|
|
||||||
statement.setTimestamp(2, chapter.getStartDate());
|
|
||||||
statement.setTimestamp(3, chapter.getEndDate());
|
|
||||||
return (statement.executeUpdate() >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean adminAddPuzzle(Puzzle puzzle, int chapter) throws SQLException {
|
|
||||||
PreparedStatement statement = Query.ADD_PUZZLE.prepare(this);
|
|
||||||
statement.setString(1, puzzle.getName());
|
|
||||||
statement.setString(2, puzzle.getContent());
|
|
||||||
statement.setBytes(3, puzzle.getSoluce());
|
|
||||||
statement.setString(4, "");
|
|
||||||
statement.setInt(5, puzzle.getScoreMax());
|
|
||||||
statement.setInt(6, chapter);
|
|
||||||
return (statement.executeUpdate() >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean adminAddTag(String name) throws SQLException {
|
|
||||||
PreparedStatement statement = Query.ADD_TAG.prepare(this);
|
|
||||||
statement.setString(1, name);
|
|
||||||
return (statement.executeUpdate() >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean adminUpdateChapter(int id, Chapter chapter) throws SQLException {
|
|
||||||
PreparedStatement statement = Query.EDIT_CHAPTER.prepare(this);
|
|
||||||
statement.setString(1, chapter.getName());
|
|
||||||
statement.setTimestamp(2, chapter.getStartDate());
|
|
||||||
statement.setTimestamp(3, chapter.getEndDate());
|
|
||||||
statement.setInt(4, id);
|
|
||||||
return (statement.executeUpdate() >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean adminUpdatePuzzle(int id, Puzzle puzzle, int chapter) throws SQLException {
|
|
||||||
PreparedStatement statement = Query.EDIT_PUZZLE.prepare(this);
|
|
||||||
statement.setString(1, puzzle.getName());
|
|
||||||
statement.setString(2, puzzle.getContent());
|
|
||||||
statement.setBytes(3, puzzle.getSoluce());
|
|
||||||
statement.setString(4, "");
|
|
||||||
statement.setInt(5, puzzle.getScoreMax());
|
|
||||||
statement.setInt(6, chapter);
|
|
||||||
statement.setInt(7, id);
|
|
||||||
return (statement.executeUpdate() >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean adminUpdateTag(Tag tag) throws SQLException {
|
|
||||||
PreparedStatement statement = Query.EDIT_TAG.prepare(this);
|
|
||||||
statement.setString(1, tag.getName());
|
|
||||||
statement.setInt(2, tag.getId());
|
|
||||||
return (statement.executeUpdate() >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean adminDeleteChapter(int id) throws SQLException {
|
|
||||||
PreparedStatement statement = Query.DELETE_CHAPTER.prepare(this);
|
|
||||||
statement.setInt(1, id);
|
|
||||||
return (statement.executeUpdate() >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean adminDeletePuzzle(int id) throws SQLException {
|
|
||||||
PreparedStatement statement = Query.DELETE_PUZZLE.prepare(this);
|
|
||||||
statement.setInt(1, id);
|
|
||||||
return (statement.executeUpdate() >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean adminDeleteTag(int id) throws SQLException {
|
|
||||||
PreparedStatement statement = Query.DELETE_TAG.prepare(this);
|
|
||||||
statement.setInt(1, id);
|
|
||||||
return (statement.executeUpdate() >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,167 +0,0 @@
|
||||||
package dev.peerat.backend.repository;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
|
|
||||||
import com.password4j.Password;
|
|
||||||
|
|
||||||
import dev.peerat.backend.Configuration;
|
|
||||||
|
|
||||||
public class DatabaseAuthRepository extends BaseDatabaseQuery{
|
|
||||||
|
|
||||||
private static enum Query{
|
|
||||||
|
|
||||||
// REGISTER
|
|
||||||
CHECK_PSEUDO_AVAILABLE_QUERY("SELECT * FROM players WHERE pseudo = ?"),
|
|
||||||
CHECK_EMAIL_AVAILABLE_QUERY("SELECT * FROM players WHERE email = ?"),
|
|
||||||
REGISTER_QUERY(
|
|
||||||
"INSERT INTO players (pseudo, email, passwd, firstname, lastname, description, avatar) VALUES (?, ?, ?, ?, ?, ?, ?)"),
|
|
||||||
REGISTER_PLAYER_IN_EXISTING_GROUP(
|
|
||||||
"INSERT INTO containsGroups (fk_player, fk_group) VALUES (?, (SELECT id_group FROM groups WHERE name = ?));"),
|
|
||||||
|
|
||||||
// LOGIN
|
|
||||||
CHECK_PASSWORD("SELECT id_player, passwd FROM players WHERE pseudo=?");
|
|
||||||
|
|
||||||
private String request;
|
|
||||||
|
|
||||||
Query(Query parent, String request) {
|
|
||||||
this.request = parent.request + request;
|
|
||||||
}
|
|
||||||
|
|
||||||
Query(String request) {
|
|
||||||
this.request = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
|
|
||||||
return base.prepare(this.request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.request;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Configuration config;
|
|
||||||
|
|
||||||
public DatabaseAuthRepository(ConnectionManager con, Configuration config){
|
|
||||||
super(con);
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a pseudo is available
|
|
||||||
*
|
|
||||||
* @param pseudo The pseudo to check
|
|
||||||
* @return True if the pseudo is available, false if it's already taken
|
|
||||||
*/
|
|
||||||
public boolean checkPseudoAvailability(String pseudo) {
|
|
||||||
return checkAvailability(pseudo, Query.CHECK_PSEUDO_AVAILABLE_QUERY.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if an email is available
|
|
||||||
*
|
|
||||||
* @param email The email to check
|
|
||||||
* @return True if the email is available, false if it's already taken
|
|
||||||
*/
|
|
||||||
public boolean checkEmailAvailability(String email) {
|
|
||||||
return checkAvailability(email, Query.CHECK_EMAIL_AVAILABLE_QUERY.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkAvailability(String queriedString, String correspondingQuery) {
|
|
||||||
try {
|
|
||||||
PreparedStatement statement = prepare(correspondingQuery);
|
|
||||||
statement.setString(1, queriedString);
|
|
||||||
ResultSet result = statement.executeQuery();
|
|
||||||
return !result.next();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a new user
|
|
||||||
*
|
|
||||||
* @param pseudo The pseudo of the user
|
|
||||||
* @param email The email of the user
|
|
||||||
* @param password The password of the user
|
|
||||||
* @param firstname The firstname of the user
|
|
||||||
* @param lastname The lastname of the user
|
|
||||||
* @param description The description of the user
|
|
||||||
* @param sgroup The group of the user
|
|
||||||
* @param avatar The avatar of the user
|
|
||||||
* @return True if the user was registered, false if an error occurred
|
|
||||||
*/
|
|
||||||
public int register(String pseudo, String email, String password, String firstname, String lastname,
|
|
||||||
String description, String sgroup, String avatar) {
|
|
||||||
try {
|
|
||||||
String pass = Password.hash(password).withArgon2().getResult();
|
|
||||||
System.out.println("pass("+pass.length()+") "+pass);
|
|
||||||
Connection con = ensureConnection();
|
|
||||||
con.setAutoCommit(false);
|
|
||||||
try (PreparedStatement playerStatement = con.prepareStatement(Query.REGISTER_QUERY.toString(),
|
|
||||||
Statement.RETURN_GENERATED_KEYS)) {
|
|
||||||
playerStatement.setString(1, pseudo);
|
|
||||||
playerStatement.setString(2, email);
|
|
||||||
playerStatement.setString(3, Password.hash(password).withArgon2().getResult());
|
|
||||||
playerStatement.setString(4, firstname);
|
|
||||||
playerStatement.setString(5, lastname);
|
|
||||||
playerStatement.setString(6, description);
|
|
||||||
playerStatement.setString(7, avatar);
|
|
||||||
if (playerStatement.executeUpdate() == 1) {
|
|
||||||
ResultSet inserted = playerStatement.getGeneratedKeys();
|
|
||||||
if (inserted.next()) {
|
|
||||||
int newPlayerId = inserted.getInt(1);
|
|
||||||
if (!sgroup.isEmpty()) {
|
|
||||||
try (PreparedStatement containsGroupsStatement = con
|
|
||||||
.prepareStatement(Query.REGISTER_PLAYER_IN_EXISTING_GROUP.toString())) {
|
|
||||||
containsGroupsStatement.setInt(1, newPlayerId);
|
|
||||||
containsGroupsStatement.setString(2, sgroup);
|
|
||||||
containsGroupsStatement.executeUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
con.commit();
|
|
||||||
con.setAutoCommit(true);
|
|
||||||
return newPlayerId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
con.rollback();
|
|
||||||
con.setAutoCommit(true);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Login a user
|
|
||||||
*
|
|
||||||
* @param username The username of the user
|
|
||||||
* @param password The password of the user
|
|
||||||
* @return id the id of the user, -1 if not login successefuly
|
|
||||||
*/
|
|
||||||
public int login(String username, String password) {
|
|
||||||
try {
|
|
||||||
ensureConnection();
|
|
||||||
PreparedStatement statement = prepare(Query.CHECK_PASSWORD.toString());
|
|
||||||
statement.setString(1, username);
|
|
||||||
ResultSet result = statement.executeQuery();
|
|
||||||
if (result.next()) {
|
|
||||||
String hashedPassword = result.getString("passwd");
|
|
||||||
if (Password.check(password, hashedPassword).withArgon2())
|
|
||||||
return result.getInt("id_player");
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
package dev.peerat.backend.repository;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import dev.peerat.backend.Configuration;
|
|
||||||
import dev.peerat.backend.model.Badge;
|
|
||||||
import dev.peerat.backend.model.Puzzle;
|
|
||||||
|
|
||||||
public class DatabaseBadgeRepository extends BaseDatabaseQuery{
|
|
||||||
|
|
||||||
public static String GET_BADGES_OF_PLAYER(){
|
|
||||||
return Query.GET_BADGES_OF_PLAYER.request;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static enum Query{
|
|
||||||
|
|
||||||
// BADGES
|
|
||||||
GET_BADGE("SELECT * FROM badges WHERE id_badge = ?"),
|
|
||||||
GET_BADGES_OF_PLAYER(
|
|
||||||
"SELECT * FROM badges b LEFT JOIN containsBadges cb ON cb.fk_badge = b.id_badge WHERE cb.fk_player = ?");
|
|
||||||
|
|
||||||
|
|
||||||
private String request;
|
|
||||||
|
|
||||||
Query(Query parent, String request) {
|
|
||||||
this.request = parent.request + request;
|
|
||||||
}
|
|
||||||
|
|
||||||
Query(String request) {
|
|
||||||
this.request = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
|
|
||||||
return base.prepare(this.request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.request;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Configuration config;
|
|
||||||
|
|
||||||
public DatabaseBadgeRepository(ConnectionManager con, Configuration config){
|
|
||||||
super(con);
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Badge getBadge(int badgeId) {
|
|
||||||
try {
|
|
||||||
ensureConnection();
|
|
||||||
PreparedStatement completionsStmt = Query.GET_BADGE.prepare(this);
|
|
||||||
completionsStmt.setInt(1, badgeId);
|
|
||||||
ResultSet result = completionsStmt.executeQuery();
|
|
||||||
if (result.next()) {
|
|
||||||
return makeBadge(result);
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,122 +0,0 @@
|
||||||
package dev.peerat.backend.repository;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import dev.peerat.backend.Configuration;
|
|
||||||
import dev.peerat.backend.model.Chapter;
|
|
||||||
import dev.peerat.backend.model.Puzzle;
|
|
||||||
|
|
||||||
public class DatabaseChapterRepository extends BaseDatabaseQuery{
|
|
||||||
|
|
||||||
private static enum Query{
|
|
||||||
|
|
||||||
// CHAPTERS
|
|
||||||
SPECIFIC_CHAPTER_QUERY("SELECT * FROM chapters WHERE id_chapter = ?"),
|
|
||||||
CHAPTER_FROM_PUZZLE("SELECT c.*\r\n"
|
|
||||||
+ "FROM chapters c\r\n"
|
|
||||||
+ "JOIN puzzles p ON p.fk_chapter = c.id_chapter\r\n"
|
|
||||||
+ "WHERE p.id_puzzle = ?"),
|
|
||||||
ALL_CHAPTERS_QUERY("SELECT * FROM chapters WHERE id_chapter > 0");
|
|
||||||
|
|
||||||
|
|
||||||
private String request;
|
|
||||||
|
|
||||||
Query(Query parent, String request) {
|
|
||||||
this.request = parent.request + request;
|
|
||||||
}
|
|
||||||
|
|
||||||
Query(String request) {
|
|
||||||
this.request = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
|
|
||||||
return base.prepare(this.request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.request;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Configuration config;
|
|
||||||
private DatabasePuzzleRepository puzzleRepo;
|
|
||||||
|
|
||||||
public DatabaseChapterRepository(ConnectionManager con, Configuration config, DatabasePuzzleRepository puzzleRepo){
|
|
||||||
super(con);
|
|
||||||
this.config = config;
|
|
||||||
this.puzzleRepo = puzzleRepo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a specific chapter
|
|
||||||
*
|
|
||||||
* @param id The id of the chapter
|
|
||||||
* @return The chapter or null if an error occurred
|
|
||||||
*/
|
|
||||||
public Chapter getChapter(int id) {
|
|
||||||
try {
|
|
||||||
ensureConnection();
|
|
||||||
PreparedStatement chapterStmt = Query.SPECIFIC_CHAPTER_QUERY.prepare(this);
|
|
||||||
chapterStmt.setInt(1, id);
|
|
||||||
ResultSet chapterResult = chapterStmt.executeQuery();
|
|
||||||
if (chapterResult.next()) {
|
|
||||||
Chapter chapter = makeChapter(chapterResult);
|
|
||||||
List<Puzzle> puzzles = puzzleRepo.getPuzzlesInChapter(id);
|
|
||||||
chapter.setPuzzles(puzzles);
|
|
||||||
return chapter;
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Chapter getChapter(Puzzle puzzle){
|
|
||||||
try {
|
|
||||||
ensureConnection();
|
|
||||||
PreparedStatement chapterStmt = Query.CHAPTER_FROM_PUZZLE.prepare(this);
|
|
||||||
chapterStmt.setInt(1, puzzle.getId());
|
|
||||||
ResultSet chapterResult = chapterStmt.executeQuery();
|
|
||||||
if (chapterResult.next()) {
|
|
||||||
Chapter chapter = makeChapter(chapterResult);
|
|
||||||
List<Puzzle> puzzles = puzzleRepo.getPuzzlesInChapter(chapter.getId());
|
|
||||||
chapter.setPuzzles(puzzles);
|
|
||||||
return chapter;
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all chapters in the database
|
|
||||||
*
|
|
||||||
* @return List of all chapters or null if an error occurred
|
|
||||||
*/
|
|
||||||
public List<Chapter> getAllChapters() {
|
|
||||||
try {
|
|
||||||
List<Chapter> chapterList = new ArrayList<>();
|
|
||||||
ensureConnection();
|
|
||||||
PreparedStatement chapterStmt = Query.ALL_CHAPTERS_QUERY.prepare(this);
|
|
||||||
ResultSet chapterResult = chapterStmt.executeQuery();
|
|
||||||
while (chapterResult.next()) {
|
|
||||||
Chapter chapter = makeChapter(chapterResult);
|
|
||||||
chapter.setPuzzles(puzzleRepo.getPuzzlesInChapter(chapter.getId()));
|
|
||||||
chapterList.add(chapter);
|
|
||||||
}
|
|
||||||
return chapterList;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,162 +0,0 @@
|
||||||
package dev.peerat.backend.repository;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import dev.peerat.backend.Configuration;
|
|
||||||
import dev.peerat.backend.model.Completion;
|
|
||||||
import dev.peerat.backend.model.Puzzle;
|
|
||||||
|
|
||||||
public class DatabaseCompletionRepository extends BaseDatabaseQuery{
|
|
||||||
|
|
||||||
private static enum Query{
|
|
||||||
|
|
||||||
// COMPLETIONS
|
|
||||||
GET_COMPLETION(
|
|
||||||
"SELECT * FROM completions WHERE fk_puzzle = ? AND fk_player = ?"),
|
|
||||||
GET_COMPLETION_GROUP("SELECT c.*\r\n"
|
|
||||||
+ "FROM completions c\r\n"
|
|
||||||
+ "WHERE c.fk_puzzle = ? AND c.fk_player IN\r\n"
|
|
||||||
+ "(select f.fk_player FROM containsGroups cgs JOIN containsGroups f ON f.fk_group = cgs.fk_group JOIN groups g ON g.id_group = cgs.fk_group WHERE g.fk_chapter = 12 AND cgs.fk_player = ?)"),
|
|
||||||
INSERT_COMPLETION(
|
|
||||||
"INSERT INTO completions (fk_puzzle, fk_player, tries, code, fileName, score) values (?, ?, ?, ?, ?, ?)"),
|
|
||||||
UPDATE_COMPLETION(
|
|
||||||
"UPDATE completions SET tries = ?, score = ?, fk_player = ? WHERE fk_puzzle = ? AND fk_player = ?"),
|
|
||||||
SCORE("SELECT score FROM completions WHERE fk_player = ? AND fk_puzzle = ?"),
|
|
||||||
SCORE_GROUP("SELECT c.score\r\n"
|
|
||||||
+ "FROM completions c\r\n"
|
|
||||||
+ "WHERE c.fk_puzzle = ? AND c.fk_player IN\r\n"
|
|
||||||
+ "(select f.fk_player FROM containsGroups cgs JOIN containsGroups f ON f.fk_group = cgs.fk_group JOIN groups g ON g.id_group = cgs.fk_group WHERE g.fk_chapter = 12 AND cgs.fk_player = ?)");
|
|
||||||
|
|
||||||
private String request;
|
|
||||||
|
|
||||||
Query(Query parent, String request) {
|
|
||||||
this.request = parent.request + request;
|
|
||||||
}
|
|
||||||
|
|
||||||
Query(String request) {
|
|
||||||
this.request = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
|
|
||||||
return base.prepare(this.request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.request;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Configuration config;
|
|
||||||
private DatabaseChapterRepository chapterRepo;
|
|
||||||
|
|
||||||
public DatabaseCompletionRepository(ConnectionManager con, Configuration config, DatabaseChapterRepository chapterRepo){
|
|
||||||
super(con);
|
|
||||||
this.config = config;
|
|
||||||
this.chapterRepo = chapterRepo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Completion getCompletionGroup(int user, int puzzle) {
|
|
||||||
try {
|
|
||||||
PreparedStatement stmt = Query.GET_COMPLETION_GROUP.prepare(this);
|
|
||||||
stmt.setInt(1, puzzle);
|
|
||||||
stmt.setInt(2, user);
|
|
||||||
ResultSet result = stmt.executeQuery();
|
|
||||||
if (result.next())
|
|
||||||
return makeCompletion(result);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return getCompletion(user, puzzle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Completion getCompletion(int playerId, int puzzleId) {
|
|
||||||
try {
|
|
||||||
PreparedStatement completionsStmt = Query.GET_COMPLETION.prepare(this);
|
|
||||||
completionsStmt.setInt(1, puzzleId);
|
|
||||||
completionsStmt.setInt(2, playerId);
|
|
||||||
ResultSet result = completionsStmt.executeQuery();
|
|
||||||
if (result.next()) {
|
|
||||||
return makeCompletion(result);
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Completion insertOrUpdatePuzzleResponse(int puzzleId, int userId, String fileName, byte[] code,
|
|
||||||
byte[] response, Puzzle currentPuzzle){
|
|
||||||
try {
|
|
||||||
ensureConnection();
|
|
||||||
Completion completion = getCompletionGroup(userId, puzzleId);
|
|
||||||
if (completion == null){
|
|
||||||
System.out.println("Completion is null");
|
|
||||||
completion = new Completion(userId, puzzleId, fileName, code, response, currentPuzzle);
|
|
||||||
insertCompletion(completion);
|
|
||||||
} else {
|
|
||||||
System.out.println(completion);
|
|
||||||
completion.addTry(currentPuzzle, response, chapterRepo.getChapter(currentPuzzle).getId());
|
|
||||||
int lastUserId = completion.getPlayerId();
|
|
||||||
completion.updatePlayer(userId);
|
|
||||||
updateCompletion(completion, lastUserId);
|
|
||||||
}
|
|
||||||
return completion;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void insertCompletion(Completion newCompletion) throws SQLException {
|
|
||||||
PreparedStatement statement = Query.INSERT_COMPLETION.prepare(this);
|
|
||||||
statement.setInt(1, newCompletion.getPuzzleId());
|
|
||||||
statement.setInt(2, newCompletion.getPlayerId());
|
|
||||||
statement.setInt(3, newCompletion.getTries());
|
|
||||||
statement.setBytes(4, newCompletion.getCode());
|
|
||||||
statement.setString(5, newCompletion.getFileName());
|
|
||||||
statement.setInt(6, newCompletion.getScore());
|
|
||||||
statement.executeUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void updateCompletion(Completion completionToUpdate, int user) throws SQLException{
|
|
||||||
System.out.println("update "+completionToUpdate);
|
|
||||||
PreparedStatement statement = Query.UPDATE_COMPLETION.prepare(this);
|
|
||||||
statement.setInt(1, completionToUpdate.getTries());
|
|
||||||
statement.setInt(2, completionToUpdate.getScore());
|
|
||||||
statement.setInt(3, completionToUpdate.getPlayerId());
|
|
||||||
statement.setInt(4, completionToUpdate.getPuzzleId());
|
|
||||||
statement.setInt(5, user);
|
|
||||||
statement.executeUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getScore(int user, int puzzle) {
|
|
||||||
try {
|
|
||||||
ensureConnection();
|
|
||||||
PreparedStatement stmt = Query.SCORE_GROUP.prepare(this);
|
|
||||||
stmt.setInt(1, puzzle);
|
|
||||||
stmt.setInt(2, user);
|
|
||||||
ResultSet result = stmt.executeQuery();
|
|
||||||
if (result.next())
|
|
||||||
return result.getInt("score");
|
|
||||||
|
|
||||||
stmt = Query.SCORE.prepare(this);
|
|
||||||
stmt.setInt(1, user);
|
|
||||||
stmt.setInt(2, puzzle);
|
|
||||||
|
|
||||||
result = stmt.executeQuery();
|
|
||||||
if (result.next())
|
|
||||||
return result.getInt("score");
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,166 +0,0 @@
|
||||||
package dev.peerat.backend.repository;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import dev.peerat.backend.Configuration;
|
|
||||||
import dev.peerat.backend.model.Group;
|
|
||||||
import dev.peerat.backend.model.PeerAtUser;
|
|
||||||
|
|
||||||
public class DatabaseGroupRepository extends BaseDatabaseQuery{
|
|
||||||
|
|
||||||
private static enum Query{
|
|
||||||
|
|
||||||
// GROUPS
|
|
||||||
ALL_GROUPS("SELECT * FROM groups"),
|
|
||||||
ALL_GROUPS_BY_CHAPTER("select g.*, count(cg.fk_player) as countPlayer from groups g left join containsGroups cg on cg.fk_group = g.id_group where g.fk_chapter = ? group by g.id_group"),
|
|
||||||
GET_GROUP_FOR_PLAYER("SELECT g.* FROM groups g JOIN containsGroups cg ON cg.fk_group = g.id_group WHERE cg.fk_player = ? AND g.fk_chapter = ?"), // AND g.fk_puzzle = ?
|
|
||||||
GET_GROUP_ID_BY_DATA("SELECT id_group FROM groups WHERE name = ? AND (fk_chapter = ?)"), // OR fk_puzzle = ?
|
|
||||||
GET_GROUP_USERS_COUNT("SELECT count(*) as howmany FROM containsGroups WHERE fk_group = ?"),
|
|
||||||
INSERT_GROUP("INSERT INTO groups (name, fk_chapter) VALUES (?,?)"),
|
|
||||||
INSERT_PLAYER_IN_GROUP("INSERT INTO containsGroups (fk_player, fk_group) VALUES (?,?)"),
|
|
||||||
LEAVE_GROUP("DELETE FROM containsGroups WHERE fk_player = ? AND fk_group = ?");
|
|
||||||
|
|
||||||
private String request;
|
|
||||||
|
|
||||||
Query(Query parent, String request) {
|
|
||||||
this.request = parent.request + request;
|
|
||||||
}
|
|
||||||
|
|
||||||
Query(String request) {
|
|
||||||
this.request = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
|
|
||||||
return base.prepare(this.request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.request;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Configuration config;
|
|
||||||
|
|
||||||
public DatabaseGroupRepository(ConnectionManager con, Configuration config){
|
|
||||||
super(con);
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Group> getAllGroups() {
|
|
||||||
try {
|
|
||||||
ensureConnection();
|
|
||||||
List<Group> list = new ArrayList<>();
|
|
||||||
PreparedStatement stmt = Query.ALL_GROUPS.prepare(this);
|
|
||||||
ResultSet groupResult = stmt.executeQuery();
|
|
||||||
while (groupResult.next())
|
|
||||||
list.add(makeGroup(groupResult));
|
|
||||||
return list;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Group> getAllGroupsByChapter(int chapter){
|
|
||||||
try {
|
|
||||||
ensureConnection();
|
|
||||||
List<Group> list = new ArrayList<>();
|
|
||||||
PreparedStatement stmt = Query.ALL_GROUPS_BY_CHAPTER.prepare(this);
|
|
||||||
stmt.setInt(1, chapter);
|
|
||||||
ResultSet groupResult = stmt.executeQuery();
|
|
||||||
while (groupResult.next())
|
|
||||||
list.add(makeGroup(groupResult));
|
|
||||||
return list;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean insertGroup(Group group, PeerAtUser creator) throws SQLException {
|
|
||||||
Integer groupId = getGroupId(group);
|
|
||||||
if (groupId == null)
|
|
||||||
ensureConnection();
|
|
||||||
PreparedStatement statement = Query.INSERT_GROUP.prepare(this);
|
|
||||||
statement.setString(1, group.getName());
|
|
||||||
statement.setObject(2, group.getLinkToChapter());
|
|
||||||
// statement.setObject(3, group.getLinkToPuzzle());
|
|
||||||
if (statement.executeUpdate() >= 0)
|
|
||||||
return insertUserInGroup(group, creator);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Group getPlayerGroup(int user, Integer chapter) throws SQLException {
|
|
||||||
ensureConnection();
|
|
||||||
PreparedStatement stmt = Query.GET_GROUP_FOR_PLAYER.prepare(this);
|
|
||||||
stmt.setInt(1, user);
|
|
||||||
stmt.setObject(2, chapter);
|
|
||||||
// stmt.setObject(3, puzzle);
|
|
||||||
|
|
||||||
ResultSet result = stmt.executeQuery();
|
|
||||||
if (result.next())
|
|
||||||
return makeGroup(result);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getGroupId(Group group) throws SQLException {
|
|
||||||
ensureConnection();
|
|
||||||
PreparedStatement stmt = Query.GET_GROUP_ID_BY_DATA.prepare(this);
|
|
||||||
stmt.setString(1, group.getName());
|
|
||||||
stmt.setObject(2, group.getLinkToChapter());
|
|
||||||
// stmt.setObject(3, group.getLinkToPuzzle());
|
|
||||||
|
|
||||||
ResultSet result = stmt.executeQuery();
|
|
||||||
if (result.next())
|
|
||||||
return result.getInt("id_group");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean insertUserInGroup(Group group, PeerAtUser user) throws SQLException{
|
|
||||||
Integer id = getGroupId(group);
|
|
||||||
if(id != null){
|
|
||||||
int howmany = numberInGroup(id);
|
|
||||||
System.out.println("join group, already have "+howmany);
|
|
||||||
if(howmany > config.getGroupMaxPlayers()) return false;
|
|
||||||
}
|
|
||||||
Group alreadyInGroup = getPlayerGroup(user.getId(), group.getLinkToChapter());
|
|
||||||
if (id != null && alreadyInGroup == null) {
|
|
||||||
PreparedStatement stmt = Query.INSERT_PLAYER_IN_GROUP.prepare(this);
|
|
||||||
|
|
||||||
stmt.setInt(1, user.getId());
|
|
||||||
stmt.setInt(2, id);
|
|
||||||
|
|
||||||
return stmt.executeUpdate() >= 0;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int numberInGroup(int group) throws SQLException{
|
|
||||||
PreparedStatement stmt = Query.GET_GROUP_USERS_COUNT.prepare(this);
|
|
||||||
stmt.setInt(1, group);
|
|
||||||
|
|
||||||
ResultSet result = stmt.executeQuery();
|
|
||||||
if(result.next()) return result.getInt("howmany");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean leaveGroup(Group group, PeerAtUser user) throws SQLException {
|
|
||||||
Integer id = getGroupId(group);
|
|
||||||
if (id != null) {
|
|
||||||
PreparedStatement stmt = Query.LEAVE_GROUP.prepare(this);
|
|
||||||
|
|
||||||
stmt.setInt(1, user.getId());
|
|
||||||
stmt.setInt(2, id);
|
|
||||||
|
|
||||||
return stmt.executeUpdate() >= 0;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,102 +0,0 @@
|
||||||
package dev.peerat.backend.repository;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.SortedSet;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
import dev.peerat.backend.Configuration;
|
|
||||||
import dev.peerat.backend.model.Group;
|
|
||||||
import dev.peerat.backend.model.Player;
|
|
||||||
|
|
||||||
public class DatabaseLeaderboardRepository extends BaseDatabaseQuery{
|
|
||||||
|
|
||||||
private static enum Query{
|
|
||||||
|
|
||||||
// LEADERBOARD
|
|
||||||
ALL_PLAYERS_FOR_LEADERBOARD(
|
|
||||||
"select p.*, scores.*, g.* from players p ,(SELECT fk_player, SUM(c.score) AS score, COUNT(c.id_completion) AS completions, SUM(c.tries) AS tries, rank() over(ORDER BY score DESC) AS rank FROM completions c LEFT JOIN puzzles puzz on puzz.id_puzzle = c.fk_puzzle LEFT JOIN chapters chap on chap.id_chapter = puzz.fk_chapter WHERE chap.id_chapter > 1 GROUP BY c.fk_player) AS scores LEFT JOIN containsGroups cg ON scores.fk_player = cg.fk_player LEFT JOIN groups g ON cg.fk_group = g.id_group WHERE p.id_player = scores.fk_player ORDER BY g.fk_chapter"),
|
|
||||||
ALL_GROUP_FOR_CHAPTER_LEADERBOARD(
|
|
||||||
"SELECT g.*, pl.pseudo, co.score, co.tries FROM groups g LEFT JOIN containsGroups cg ON g.id_group = cg.fk_group LEFT JOIN players pl ON cg.fk_player = pl.id_player LEFT JOIN completions co ON pl.id_player = co.fk_player WHERE cg.fk_player IS NOT NULL AND fk_chapter = ? AND (co.fk_puzzle IN (SELECT id_puzzle FROM puzzles puz WHERE puz.fk_chapter = g.fk_chapter) OR co.score IS NULL);");
|
|
||||||
|
|
||||||
private String request;
|
|
||||||
|
|
||||||
Query(Query parent, String request) {
|
|
||||||
this.request = parent.request + request;
|
|
||||||
}
|
|
||||||
|
|
||||||
Query(String request) {
|
|
||||||
this.request = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
|
|
||||||
return base.prepare(this.request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.request;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Configuration config;
|
|
||||||
|
|
||||||
public DatabaseLeaderboardRepository(ConnectionManager con, Configuration config){
|
|
||||||
super(con);
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SortedSet<Player> getAllPlayerForLeaderboard() {
|
|
||||||
try {
|
|
||||||
ensureConnection();
|
|
||||||
PreparedStatement playersStmt = Query.ALL_PLAYERS_FOR_LEADERBOARD.prepare(this);
|
|
||||||
ResultSet result = playersStmt.executeQuery();
|
|
||||||
ArrayList<Player> players = new ArrayList<Player>();
|
|
||||||
Player tmpPlayer;
|
|
||||||
while (result.next()) {
|
|
||||||
tmpPlayer = makePlayer(result, result.getInt("id_player"));
|
|
||||||
if (!players.contains(tmpPlayer)) {
|
|
||||||
players.add(tmpPlayer);
|
|
||||||
} else {
|
|
||||||
players.get(players.indexOf(tmpPlayer)).addGroup(makeGroup(result));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new TreeSet<Player>(players);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SortedSet<Group> getAllGroupForChapterLeaderboard(int chapterId){
|
|
||||||
try{
|
|
||||||
ensureConnection();
|
|
||||||
PreparedStatement groupsStmt = Query.ALL_GROUP_FOR_CHAPTER_LEADERBOARD.prepare(this);
|
|
||||||
groupsStmt.setInt(1, chapterId);
|
|
||||||
ResultSet result = groupsStmt.executeQuery();
|
|
||||||
List<Group> groups = new ArrayList<Group>();
|
|
||||||
Group tmpGroup;
|
|
||||||
while (result.next()) {
|
|
||||||
tmpGroup = makeGroup(result);
|
|
||||||
if (tmpGroup != null) {
|
|
||||||
int gPosition = groups.indexOf(tmpGroup);
|
|
||||||
if (gPosition < 0) {
|
|
||||||
tmpGroup.addPlayer(makeGroupPlayer(result));
|
|
||||||
groups.add(tmpGroup);
|
|
||||||
} else {
|
|
||||||
groups.get(gPosition).addPlayer(makeGroupPlayer(result));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new TreeSet<Group>(groups);
|
|
||||||
}catch(SQLException e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,191 +0,0 @@
|
||||||
package dev.peerat.backend.repository;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.password4j.Password;
|
|
||||||
|
|
||||||
import dev.peerat.backend.Configuration;
|
|
||||||
import dev.peerat.backend.model.Player;
|
|
||||||
import dev.peerat.backend.model.Puzzle;
|
|
||||||
|
|
||||||
public class DatabasePlayerRepository extends BaseDatabaseQuery{
|
|
||||||
|
|
||||||
public static String GET_PLAYER_RANK(){
|
|
||||||
return Query.GET_PLAYER_RANK.request;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static enum Query{
|
|
||||||
|
|
||||||
// PLAYERS
|
|
||||||
GET_PLAYER_SIMPLE("SELECT pseudo, email, firstname, lastname, description FROM players WHERE id_player = ?"),
|
|
||||||
GET_PLAYER_EMAIL("SELECT id_player FROM players WHERE email = ?"),
|
|
||||||
GET_PLAYER_PSEUDO("SELECT * FROM players WHERE pseudo = ?"),
|
|
||||||
GET_PLAYER_DETAILS("SELECT p.*, g.*\r\n"
|
|
||||||
+ "FROM players p\r\n"
|
|
||||||
+ "LEFT OUTER JOIN containsGroups cg ON p.id_player = cg.fk_player\r\n"
|
|
||||||
+ "LEFT OUTER JOIN groups g ON cg.fk_group = g.id_group\r\n"
|
|
||||||
+ "LEFT OUTER JOIN completions c on p.id_player = c.fk_player\r\n"
|
|
||||||
+ "WHERE "),
|
|
||||||
GET_PLAYER_DETAILS_BY_ID(GET_PLAYER_DETAILS, " p.id_player = ? GROUP BY g.name ORDER BY g.fk_chapter, g.fk_puzzle;"),
|
|
||||||
GET_PLAYER_DETAILS_BY_PSEUDO(GET_PLAYER_DETAILS, "p.pseudo = ? GROUP BY g.name ORDER BY g.fk_chapter, g.fk_puzzle;"),
|
|
||||||
GET_PLAYER_COMPLETIONS("select c.*, p.name from completions c left join puzzles p on c.fk_puzzle = p.id_puzzle where fk_player = ?;"),
|
|
||||||
GET_PLAYER_RANK("SELECT * FROM (SELECT fk_player, RANK() OVER(ORDER BY SUM(score) DESC) rank FROM completions c LEFT JOIN puzzles puzz on puzz.id_puzzle = c.fk_puzzle LEFT JOIN chapters chap on chap.id_chapter = puzz.fk_chapter LEFT JOIN players p ON p.id_player = c.fk_player WHERE chap.id_chapter > 1 GROUP BY fk_player ORDER BY rank) AS ranks WHERE ranks.fk_player = ?;"),
|
|
||||||
UPDATE_PLAYER_INFO("UPDATE players SET pseudo = ?, email = ?, firstname = ?, lastname = ? WHERE id_player = ?"),
|
|
||||||
UPDATE_PLAYER_PASSWORD("UPDATE players SET passwd = ? WHERE id_player = ?");
|
|
||||||
private String request;
|
|
||||||
|
|
||||||
Query(Query parent, String request) {
|
|
||||||
this.request = parent.request + request;
|
|
||||||
}
|
|
||||||
|
|
||||||
Query(String request) {
|
|
||||||
this.request = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
|
|
||||||
return base.prepare(this.request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.request;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Configuration config;
|
|
||||||
|
|
||||||
public DatabasePlayerRepository(ConnectionManager con, Configuration config){
|
|
||||||
super(con);
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Player getPlayer(int idPlayer) {
|
|
||||||
try {
|
|
||||||
PreparedStatement completionsStmt = Query.GET_PLAYER_SIMPLE.prepare(this);
|
|
||||||
completionsStmt.setInt(1, idPlayer);
|
|
||||||
ResultSet result = completionsStmt.executeQuery();
|
|
||||||
if (result.next()) {
|
|
||||||
return makePlayer(result, idPlayer);
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPlayerId(String email){
|
|
||||||
try {
|
|
||||||
ensureConnection();
|
|
||||||
PreparedStatement completionsStmt = Query.GET_PLAYER_EMAIL.prepare(this);
|
|
||||||
completionsStmt.setString(1, email);
|
|
||||||
ResultSet result = completionsStmt.executeQuery();
|
|
||||||
if (result.next()) {
|
|
||||||
return result.getInt("id_player");
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean updatePseudo(int id, Player player, String pseudo){
|
|
||||||
try{
|
|
||||||
PreparedStatement statment = Query.GET_PLAYER_PSEUDO.prepare(this);
|
|
||||||
statment.setString(1, pseudo);
|
|
||||||
ResultSet result = statment.executeQuery();
|
|
||||||
if(result.next()) return false;
|
|
||||||
statment = Query.UPDATE_PLAYER_INFO.prepare(this);
|
|
||||||
statment.setString(1, pseudo);
|
|
||||||
statment.setString(2, player.getEmail());
|
|
||||||
statment.setString(3, player.getFirstname());
|
|
||||||
statment.setString(4, player.getLastname());
|
|
||||||
statment.setInt(5, id);
|
|
||||||
return statment.executeUpdate() > 0;
|
|
||||||
}catch(Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateProfile(int id, Player player, String lastname, String firstname){
|
|
||||||
try{
|
|
||||||
PreparedStatement statment = Query.UPDATE_PLAYER_INFO.prepare(this);
|
|
||||||
statment.setString(1, player.getPseudo());
|
|
||||||
statment.setString(2, player.getEmail());
|
|
||||||
statment.setString(3, firstname);
|
|
||||||
statment.setString(4, lastname);
|
|
||||||
statment.setInt(5, id);
|
|
||||||
statment.executeUpdate();
|
|
||||||
}catch(Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updatePassword(int id, String password){
|
|
||||||
try{
|
|
||||||
PreparedStatement statment = Query.UPDATE_PLAYER_PASSWORD.prepare(this);
|
|
||||||
statment.setString(1, Password.hash(password).withArgon2().getResult());
|
|
||||||
statment.setInt(2, id);
|
|
||||||
statment.executeUpdate();
|
|
||||||
}catch(Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Player getPlayerDetails(int idPlayer) {
|
|
||||||
return getPlayerDetails(idPlayer, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Player getPlayerDetails(String pseudoPlayer) {
|
|
||||||
return getPlayerDetails(-1, pseudoPlayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Player getPlayerDetails(int id, String pseudo) {
|
|
||||||
try {
|
|
||||||
ensureConnection();
|
|
||||||
PreparedStatement completionsStmt;
|
|
||||||
if (pseudo != null) {
|
|
||||||
completionsStmt = Query.GET_PLAYER_DETAILS_BY_PSEUDO.prepare(this);
|
|
||||||
completionsStmt.setString(1, pseudo);
|
|
||||||
} else {
|
|
||||||
completionsStmt = Query.GET_PLAYER_DETAILS_BY_ID.prepare(this);
|
|
||||||
completionsStmt.setInt(1, id);
|
|
||||||
}
|
|
||||||
ResultSet result = completionsStmt.executeQuery();
|
|
||||||
Player player = null;
|
|
||||||
while (result.next()) {
|
|
||||||
if (player == null) {
|
|
||||||
id = result.getInt("id_player");
|
|
||||||
player = makePlayer(result, id);
|
|
||||||
completionsStmt = prepare(DatabaseBadgeRepository.GET_BADGES_OF_PLAYER());
|
|
||||||
completionsStmt.setInt(1, id);
|
|
||||||
ResultSet resultBadges = completionsStmt.executeQuery();
|
|
||||||
while (resultBadges.next()) {
|
|
||||||
player.addBadge(makeBadge(resultBadges));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
player.addGroup(makeGroup(result));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ADD completions
|
|
||||||
completionsStmt = Query.GET_PLAYER_COMPLETIONS.prepare(this);
|
|
||||||
completionsStmt.setInt(1, id);
|
|
||||||
result = completionsStmt.executeQuery();
|
|
||||||
while (result.next()) {
|
|
||||||
player.addCompletion(makeCompletion(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
return player;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
package dev.peerat.backend.repository;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import dev.peerat.backend.Configuration;
|
|
||||||
import dev.peerat.backend.model.Puzzle;
|
|
||||||
|
|
||||||
public class DatabasePuzzleRepository extends BaseDatabaseQuery{
|
|
||||||
|
|
||||||
private static enum Query{
|
|
||||||
|
|
||||||
SPECIFIC_PUZZLE_QUERY(
|
|
||||||
"SELECT p.*, np.origin, GROUP_CONCAT(t.name) AS tags FROM puzzles p LEFT JOIN nextPart np ON p.id_puzzle = np.next LEFT JOIN containsTags ct ON ct.fk_puzzle = p.id_puzzle LEFT JOIN tags t ON t.id_tag = ct.fk_tag WHERE p.id_puzzle = ? GROUP BY p.id_puzzle"),
|
|
||||||
PUZZLES_IN_CHAPTER_QUERY(
|
|
||||||
"SELECT p.*, GROUP_CONCAT(t.name) AS tags FROM puzzles p LEFT JOIN containsTags ct ON ct.fk_puzzle = p.id_puzzle LEFT JOIN tags t ON t.id_tag = ct.fk_tag WHERE fk_chapter = ? GROUP BY p.id_puzzle");
|
|
||||||
|
|
||||||
private String request;
|
|
||||||
|
|
||||||
Query(Query parent, String request) {
|
|
||||||
this.request = parent.request + request;
|
|
||||||
}
|
|
||||||
|
|
||||||
Query(String request) {
|
|
||||||
this.request = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
|
|
||||||
return base.prepare(this.request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.request;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Configuration config;
|
|
||||||
|
|
||||||
public DatabasePuzzleRepository(ConnectionManager con, Configuration config){
|
|
||||||
super(con);
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Puzzle> getPuzzlesInChapter(int id) throws SQLException {
|
|
||||||
List<Puzzle> puzzles = new ArrayList<>();
|
|
||||||
ensureConnection();
|
|
||||||
PreparedStatement puzzleStmt = Query.PUZZLES_IN_CHAPTER_QUERY.prepare(this);
|
|
||||||
puzzleStmt.setInt(1, id);
|
|
||||||
ResultSet puzzleResult = puzzleStmt.executeQuery();
|
|
||||||
while (puzzleResult.next()) {
|
|
||||||
puzzles.add(makePuzzle(puzzleResult));
|
|
||||||
}
|
|
||||||
return puzzles;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a specific puzzle
|
|
||||||
*
|
|
||||||
* @param id The id of the puzzle
|
|
||||||
* @return The puzzle or null if an error occurred
|
|
||||||
*/
|
|
||||||
public Puzzle getPuzzle(int id) throws SQLException {
|
|
||||||
ensureConnection();
|
|
||||||
PreparedStatement puzzleStmt = Query.SPECIFIC_PUZZLE_QUERY.prepare(this);
|
|
||||||
puzzleStmt.setInt(1, id);
|
|
||||||
ResultSet puzzleResult = puzzleStmt.executeQuery();
|
|
||||||
if (puzzleResult.next()) {
|
|
||||||
return makePuzzle(puzzleResult);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,181 +0,0 @@
|
||||||
package dev.peerat.backend.repository;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
public enum DatabaseQuery {
|
|
||||||
|
|
||||||
//TRIGGER
|
|
||||||
FIRST_TRY("CREATE OR REPLACE TRIGGER FirstTry\r\n"
|
|
||||||
+ "AFTER INSERT\r\n"
|
|
||||||
+ " ON completions FOR EACH ROW\r\n"
|
|
||||||
+ "BEGIN\r\n"
|
|
||||||
+ " DECLARE badge INT;\r\n"
|
|
||||||
+ " DECLARE contain INT;\r\n"
|
|
||||||
+ " \r\n"
|
|
||||||
+ " SELECT id_badge\r\n"
|
|
||||||
+ " INTO @badge\r\n"
|
|
||||||
+ " FROM badges\r\n"
|
|
||||||
+ " WHERE name = 'FirstTry';\r\n"
|
|
||||||
+ " \r\n"
|
|
||||||
+ " IF @badge is not null THEN\r\n"
|
|
||||||
+ " \r\n"
|
|
||||||
+ " SELECT count(*)\r\n"
|
|
||||||
+ " INTO @contain\r\n"
|
|
||||||
+ " FROM containsBadges\r\n"
|
|
||||||
+ " WHERE fk_badge = @badge AND fk_player = NEW.fk_player;\r\n"
|
|
||||||
+ " \r\n"
|
|
||||||
+ " IF (@contain = 0) THEN\r\n"
|
|
||||||
+ " INSERT INTO containsBadges(fk_player, fk_badge) VALUES (NEW.fk_player, @badge);\r\n"
|
|
||||||
+ " END IF;\r\n"
|
|
||||||
+ " END IF;\r\n"
|
|
||||||
+ "END;"),
|
|
||||||
EventParticipation("CREATE OR REPLACE TRIGGER EventParticipation\r\n"
|
|
||||||
+ "AFTER INSERT\r\n"
|
|
||||||
+ " ON completions FOR EACH ROW\r\n"
|
|
||||||
+ "BEGIN\r\n"
|
|
||||||
+ " DECLARE badge INT;\r\n"
|
|
||||||
+ " DECLARE endDate datetime;\r\n"
|
|
||||||
+ " DECLARE player INT;\r\n"
|
|
||||||
+ " DECLARE contain INT;\r\n"
|
|
||||||
+ "\r\n"
|
|
||||||
+ " SELECT id_badge\r\n"
|
|
||||||
+ " INTO badge\r\n"
|
|
||||||
+ " FROM badges\r\n"
|
|
||||||
+ " WHERE name = 'EventParticipation';\r\n"
|
|
||||||
+ "\r\n"
|
|
||||||
+ " IF @badge is not null THEN\r\n"
|
|
||||||
+ "\r\n"
|
|
||||||
+ " SELECT c.end_date, i.fk_player\r\n"
|
|
||||||
+ " INTO endDate, player\r\n"
|
|
||||||
+ " FROM inserted i\r\n"
|
|
||||||
+ " JOIN puzzles p ON i.fk_puzzle = p.id_puzzle\r\n"
|
|
||||||
+ " JOIN chapters c on p.fk_chapter = c.id_chapter;\r\n"
|
|
||||||
+ "\r\n"
|
|
||||||
+ " IF @endDate is not null THEN\r\n"
|
|
||||||
+ "\r\n"
|
|
||||||
+ " SELECT count(*)\r\n"
|
|
||||||
+ " INTO contain\r\n"
|
|
||||||
+ " FROM containsBadges\r\n"
|
|
||||||
+ " WHERE fk_badge = badge AND fk_player = player;\r\n"
|
|
||||||
+ "\r\n"
|
|
||||||
+ " IF (@contain = 0) THEN\r\n"
|
|
||||||
+ " INSERT INTO containsBadges(fk_player, fk_badge) VALUES (@player, @badge);\r\n"
|
|
||||||
+ " END IF;\r\n"
|
|
||||||
+ " END IF;\r\n"
|
|
||||||
+ " END IF;\r\n"
|
|
||||||
+ "END;");
|
|
||||||
|
|
||||||
private String request;
|
|
||||||
|
|
||||||
DatabaseQuery(DatabaseQuery parent, String request) {
|
|
||||||
this.request = parent.request + request;
|
|
||||||
}
|
|
||||||
|
|
||||||
DatabaseQuery(String request) {
|
|
||||||
this.request = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepare(Connection con) throws SQLException {
|
|
||||||
return con.prepareStatement(this.request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.request;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
|
|
||||||
SELECT p.*, scores.score, scores.completions, scores.tries, scores.rank, g.*
|
|
||||||
FROM players p,
|
|
||||||
(SELECT fk_player, SUM(c.score) AS score,
|
|
||||||
COUNT(c.id_completion) AS completions,
|
|
||||||
SUM(c.tries) AS tries,
|
|
||||||
rank() over(ORDER BY score DESC) AS rank
|
|
||||||
FROM completions c GROUP BY c.fk_player)
|
|
||||||
AS scores
|
|
||||||
LEFT OUTER JOIN containsGroups cg ON scores.fk_player = cg.fk_player
|
|
||||||
LEFT OUTER JOIN groups g ON cg.fk_group = g.id_group
|
|
||||||
WHERE p.id_player = scores.fk_player AND "),
|
|
||||||
|
|
||||||
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* TRIGGER PLACE
|
|
||||||
*
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER FirstTry
|
|
||||||
AFTER INSERT
|
|
||||||
ON completions FOR EACH ROW
|
|
||||||
BEGIN
|
|
||||||
DECLARE badge INT;
|
|
||||||
DECLARE contain INT;
|
|
||||||
|
|
||||||
SELECT id_badge
|
|
||||||
INTO @badge
|
|
||||||
FROM badges
|
|
||||||
WHERE name = 'FirstTry';
|
|
||||||
|
|
||||||
IF @badge is not null THEN
|
|
||||||
|
|
||||||
SELECT count(*)
|
|
||||||
INTO @contain
|
|
||||||
FROM containsBadges
|
|
||||||
WHERE fk_badge = @badge AND fk_player = NEW.fk_player;
|
|
||||||
|
|
||||||
IF (@contain = 0) THEN
|
|
||||||
|
|
||||||
IF (NEW.score >= 0 AND NEW.tries < 2) THEN
|
|
||||||
INSERT INTO containsBadges(fk_player, fk_badge) VALUES (NEW.fk_player, @badge);
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER EventParticipation
|
|
||||||
AFTER INSERT
|
|
||||||
ON completions FOR EACH ROW
|
|
||||||
BEGIN
|
|
||||||
DECLARE badge INT;
|
|
||||||
DECLARE endDate datetime;
|
|
||||||
DECLARE player INT;
|
|
||||||
DECLARE contain INT;
|
|
||||||
|
|
||||||
SELECT id_badge
|
|
||||||
INTO badge
|
|
||||||
FROM badges
|
|
||||||
WHERE name = 'EventParticipation';
|
|
||||||
|
|
||||||
IF @badge is not null THEN
|
|
||||||
|
|
||||||
SELECT c.end_date, i.fk_player
|
|
||||||
INTO endDate, player
|
|
||||||
FROM inserted i
|
|
||||||
JOIN puzzles p ON i.fk_puzzle = p.id_puzzle
|
|
||||||
JOIN chapters c on p.fk_chapter = c.id_chapter;
|
|
||||||
|
|
||||||
IF @endDate is not null THEN
|
|
||||||
|
|
||||||
SELECT count(*)
|
|
||||||
INTO contain
|
|
||||||
FROM containsBadges
|
|
||||||
WHERE fk_badge = badge AND fk_player = player;
|
|
||||||
|
|
||||||
IF (@contain = 0) THEN
|
|
||||||
INSERT INTO containsBadges(fk_player, fk_badge) VALUES (@player, @badge);
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
|
|
||||||
|
|
||||||
*
|
|
||||||
*/
|
|
|
@ -1,239 +0,0 @@
|
||||||
package dev.peerat.backend.repository;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.BufferedWriter;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.nio.file.FileSystems;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.StandardWatchEventKinds;
|
|
||||||
import java.nio.file.WatchEvent;
|
|
||||||
import java.nio.file.WatchKey;
|
|
||||||
import java.nio.file.WatchService;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import dev.peerat.backend.Configuration;
|
|
||||||
|
|
||||||
public class DatabaseRepository extends BaseDatabaseQuery{
|
|
||||||
|
|
||||||
private Connection con; //refractor chain
|
|
||||||
private Configuration config;
|
|
||||||
|
|
||||||
private DatabasePuzzleRepository puzzleRepo;
|
|
||||||
private DatabaseChapterRepository chapterRepo;
|
|
||||||
private DatabaseAdminRepository adminRepo;
|
|
||||||
private DatabaseAuthRepository authRepo;
|
|
||||||
private DatabaseBadgeRepository badgeRepo;
|
|
||||||
private DatabaseCompletionRepository completionRepo;
|
|
||||||
private DatabaseGroupRepository groupRepo;
|
|
||||||
private DatabaseLeaderboardRepository leaderboardRepo;
|
|
||||||
private DatabasePlayerRepository playerRepo;
|
|
||||||
|
|
||||||
public DatabaseRepository(ConnectionManager con, Configuration config) throws Exception {
|
|
||||||
super(con);
|
|
||||||
this.config = config;
|
|
||||||
|
|
||||||
this.puzzleRepo = new DatabasePuzzleRepository(con, config);
|
|
||||||
this.chapterRepo = new DatabaseChapterRepository(con, config, puzzleRepo);
|
|
||||||
this.adminRepo = new DatabaseAdminRepository(con, config);
|
|
||||||
this.authRepo = new DatabaseAuthRepository(con, config);
|
|
||||||
this.badgeRepo = new DatabaseBadgeRepository(con, config);
|
|
||||||
this.completionRepo = new DatabaseCompletionRepository(con, config, chapterRepo);
|
|
||||||
this.groupRepo = new DatabaseGroupRepository(con, config);
|
|
||||||
this.leaderboardRepo = new DatabaseLeaderboardRepository(con, config);
|
|
||||||
this.playerRepo = new DatabasePlayerRepository(con, config);
|
|
||||||
|
|
||||||
loadConfig(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadConfig(Configuration config) throws Exception{
|
|
||||||
String name = DatabaseRepository.class.getPackage().getName();
|
|
||||||
InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream(name.replace(".", "/"));
|
|
||||||
File folder = new File(config.getSqlFolder());
|
|
||||||
try{
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
|
|
||||||
String line;
|
|
||||||
while((line = reader.readLine()) != null){
|
|
||||||
if(line.endsWith(".class")){
|
|
||||||
Class<?> clazz = Class.forName(name+"."+line.substring(0, line.length()-6));
|
|
||||||
if(BaseDatabaseQuery.class.isAssignableFrom(clazz)){
|
|
||||||
for(Class<?> subClazz : clazz.getDeclaredClasses()){
|
|
||||||
if(subClazz.isEnum()){
|
|
||||||
configure(subClazz, folder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reader.close();
|
|
||||||
}catch(Exception e){
|
|
||||||
System.err.println("Failed to read "+name);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
new Thread(() -> {
|
|
||||||
try{
|
|
||||||
WatchService watchService = FileSystems.getDefault().newWatchService();
|
|
||||||
Path path = folder.toPath();
|
|
||||||
path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
|
|
||||||
while (true) {
|
|
||||||
WatchKey key = watchService.take();
|
|
||||||
for(WatchEvent<?> event : key.pollEvents()){
|
|
||||||
Path edited = (Path) event.context();
|
|
||||||
String targetClazz = edited.toFile().getName().split("\\.")[0];
|
|
||||||
Class<?> clazz = Class.forName(name+"."+targetClazz);
|
|
||||||
if(BaseDatabaseQuery.class.isAssignableFrom(clazz)){
|
|
||||||
for(Class<?> subClazz : clazz.getDeclaredClasses()){
|
|
||||||
if(subClazz.isEnum()){
|
|
||||||
bind(subClazz, new File(folder, edited.toFile().getName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key.reset();
|
|
||||||
}
|
|
||||||
}catch(Exception ex){
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void configure(Class<?> clazz, File folder) throws Exception{
|
|
||||||
String name = clazz.getName().split("\\$")[0];
|
|
||||||
String[] split = name.split("\\.");
|
|
||||||
File file = new File(folder, split[split.length-1]+".txt");
|
|
||||||
if(file.exists()){
|
|
||||||
bind(clazz, file);
|
|
||||||
}else{
|
|
||||||
File parent = file.getParentFile();
|
|
||||||
if(!parent.exists()) parent.mkdirs();
|
|
||||||
file.createNewFile();
|
|
||||||
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
|
|
||||||
for(Object obj : clazz.getEnumConstants()){
|
|
||||||
Enum instance = (Enum) obj;
|
|
||||||
writer.write(instance.name()+"="+instance.toString().replace("\n", " ").replace("\r", " ")+"\n");
|
|
||||||
}
|
|
||||||
writer.flush();
|
|
||||||
writer.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void bind(Class<?> clazz, File file) throws Exception{
|
|
||||||
Map<String, String> map = new HashMap<>();
|
|
||||||
BufferedReader reader = new BufferedReader(new FileReader(file));
|
|
||||||
String line;
|
|
||||||
while((line = reader.readLine()) != null){
|
|
||||||
int index = line.indexOf('=');
|
|
||||||
String key = line.substring(0, index);
|
|
||||||
String value = line.substring(index+1);
|
|
||||||
map.put(key, value);
|
|
||||||
}
|
|
||||||
reader.close();
|
|
||||||
|
|
||||||
for(Object obj : clazz.getEnumConstants()){
|
|
||||||
Enum instance = (Enum) obj;
|
|
||||||
String value = map.get(instance.name());
|
|
||||||
Field field = obj.getClass().getDeclaredField("request");
|
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(instance, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public DatabasePuzzleRepository getPuzzleRepository(){
|
|
||||||
return this.puzzleRepo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DatabaseChapterRepository getChapterRepository(){
|
|
||||||
return this.chapterRepo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DatabaseAdminRepository getAdminRepository(){
|
|
||||||
return this.adminRepo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DatabaseAuthRepository getAuthRepository(){
|
|
||||||
return this.authRepo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DatabaseBadgeRepository getBadgeRepository(){
|
|
||||||
return this.badgeRepo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DatabaseCompletionRepository getCompletionRepository(){
|
|
||||||
return this.completionRepo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DatabaseGroupRepository getGroupRepository(){
|
|
||||||
return this.groupRepo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DatabaseLeaderboardRepository getLeaderboardRepository(){
|
|
||||||
return this.leaderboardRepo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DatabasePlayerRepository getPlayerRepository(){
|
|
||||||
return this.playerRepo;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void hotfix() throws Exception{
|
|
||||||
ensureConnection();
|
|
||||||
|
|
||||||
PreparedStatement stmt = con.prepareStatement("SELECT c.*, g.* FROM completions c JOIN puzzles p ON c.fk_puzzle = p.id_puzzle JOIN containsGroups cg ON cg.fk_player = c.fk_player JOIN groups g ON g.id_group = cg.fk_group WHERE g.fk_chapter = 12 AND p.fk_chapter = 12;");
|
|
||||||
ResultSet results = stmt.executeQuery();
|
|
||||||
List<Completionz> list = new ArrayList<>();
|
|
||||||
while(results.next()){
|
|
||||||
Completionz complete = new Completionz(results);
|
|
||||||
list.add(complete);
|
|
||||||
}
|
|
||||||
Map<Integer, Map<Integer, Completionz>> map = new HashMap<>();
|
|
||||||
for(Completionz comp : list){
|
|
||||||
Map<Integer,Completionz> puz = map.get(comp.puzzle);
|
|
||||||
if(puz == null){
|
|
||||||
puz = new HashMap<>();
|
|
||||||
map.put(comp.puzzle, puz);
|
|
||||||
}
|
|
||||||
Completionz c = puz.get(comp.groups);
|
|
||||||
if(c == null){
|
|
||||||
puz.put(comp.groups, comp);
|
|
||||||
}else{
|
|
||||||
if(comp.score >= c.score){
|
|
||||||
puz.put(comp.groups, comp);
|
|
||||||
System.out.println("remove compl "+c.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Completionz{
|
|
||||||
|
|
||||||
public int id;
|
|
||||||
public int puzzle;
|
|
||||||
public int player;
|
|
||||||
public int tries;
|
|
||||||
public int score;
|
|
||||||
public int groups;
|
|
||||||
|
|
||||||
public Completionz(ResultSet result) throws Exception{
|
|
||||||
id = result.getInt("id_completion");
|
|
||||||
puzzle = result.getInt("fk_puzzle");
|
|
||||||
player = result.getInt("fk_player");
|
|
||||||
tries = result.getInt("tries");
|
|
||||||
score = result.getInt("score");
|
|
||||||
groups = result.getInt("id_group");
|
|
||||||
System.out.println(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
package dev.peerat.backend.routes;
|
|
||||||
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
|
|
||||||
import dev.peerat.backend.bonus.extract.RouteDoc;
|
|
||||||
import dev.peerat.backend.model.Badge;
|
|
||||||
import dev.peerat.backend.repository.DatabaseBadgeRepository;
|
|
||||||
import dev.peerat.backend.repository.DatabaseRepository;
|
|
||||||
import dev.peerat.framework.Context;
|
|
||||||
import dev.peerat.framework.HttpReader;
|
|
||||||
import dev.peerat.framework.HttpWriter;
|
|
||||||
import dev.peerat.framework.Response;
|
|
||||||
import dev.peerat.framework.Route;
|
|
||||||
import dev.peerat.framework.utils.json.JsonMap;
|
|
||||||
|
|
||||||
public class BadgeDetails implements Response {
|
|
||||||
|
|
||||||
private final DatabaseBadgeRepository databaseRepo;
|
|
||||||
|
|
||||||
public BadgeDetails(DatabaseRepository databaseRepo) {
|
|
||||||
this.databaseRepo = databaseRepo.getBadgeRepository();
|
|
||||||
}
|
|
||||||
|
|
||||||
@RouteDoc(path = "/badge/<id>", responseCode = 200, responseDescription = "JSON contenant les informations du badge")
|
|
||||||
@RouteDoc(responseCode = 400, responseDescription = "Aucun id donner")
|
|
||||||
|
|
||||||
@Route(path = "^\\/badge\\/([0-9]+)$", needLogin = true)
|
|
||||||
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
|
|
||||||
if (matcher.groupCount() > 0) {
|
|
||||||
int badgeId = Integer.parseInt(matcher.group(1));
|
|
||||||
Badge badge = databaseRepo.getBadge(badgeId);
|
|
||||||
JsonMap badgeJSON = new JsonMap();
|
|
||||||
if(badge != null){
|
|
||||||
badgeJSON.set("name", badge.getName());
|
|
||||||
if(badge.getLogo() != null) badgeJSON.set("logo", Base64.getEncoder().encodeToString(badge.getLogo()));
|
|
||||||
badgeJSON.set("level", badge.getLevel());
|
|
||||||
}
|
|
||||||
context.response(200);
|
|
||||||
writer.write(badgeJSON.toString().replace("\\", ""));
|
|
||||||
} else {
|
|
||||||
context.response(400);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue