Compare commits

...
Sign in to create a new pull request.

13 commits
tomcat ... main

Author SHA1 Message Date
jeffcheasey88
b47ffac3b1 Exception : Add target constructor + add exception when named dependency not found 2024-09-17 11:04:55 +02:00
jeffcheasey88
25a384cc63 Catch Errors on routes 2024-09-01 21:24:12 +02:00
jeffcheasey88
b1575e5b52 Update Dependencies Injections | Add possibility to give differente object's instance for the same object's type 2024-06-28 21:01:15 +02:00
jeffcheasey88
2c9897a7c5 Add route auto-registering (scan package + dependency injection) 2024-06-06 01:43:12 +02:00
jeffcheasey88
600de755ca JWT -> import & export private key 2024-04-16 11:51:22 +02:00
jeffcheasey88
c2e9e9e5bf Fix json parser special chars 2024-04-14 14:36:47 +02:00
jeffcheasey88
5be25735ae Catch Exception in a logger 2024-03-28 20:33:27 +01:00
jeffcheasey88
0e65f6648b Update dependencies 2024-03-28 20:29:34 +01:00
jeffcheasey88
7bbfeea23a Route Interceptor....with method is better 2024-03-13 11:19:06 +01:00
jeffcheasey88
d6ca7c5092 Add Route Interceptor system 2024-03-13 11:07:47 +01:00
jeffcheasey88
2f8f158e2a Add possibility to get all Headers sended + Complete http response message 2024-02-19 11:14:45 +01:00
jeffcheasey88
7be045fdb4 Parse double + fix Boolean parse 2023-12-21 23:07:07 +01:00
jeffcheasey88
700aa28779 Remove duplicate variable context 2023-12-21 22:59:28 +01:00
17 changed files with 274 additions and 60 deletions

View file

@ -2,9 +2,9 @@
<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"/>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry exported="true" kind="lib" path="jose4j-0.9.3.jar"/> <classpathentry exported="true" kind="lib" path="jose4j-0.9.6.jar"/>
<classpathentry exported="true" kind="lib" path="password4j-1.6.3.jar"/> <classpathentry exported="true" kind="lib" path="password4j-1.8.1.jar"/>
<classpathentry exported="true" kind="lib" path="slf4j-api-2.0.6.jar"/> <classpathentry exported="true" kind="lib" path="slf4j-api-2.0.12.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/jeffc/eclipse-workspace/peer-at-code-framework/PeerAtCodeParser.jar"/> <classpathentry exported="true" kind="lib" path="PeerAtCodeParser.jar"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>

Binary file not shown.

BIN
password4j-1.8.1.jar Normal file

Binary file not shown.

BIN
slf4j-api-2.0.12.jar Normal file

Binary file not shown.

Binary file not shown.

View file

@ -9,13 +9,11 @@ public class Client<U extends User> extends Thread{
private HttpReader reader; private HttpReader reader;
private HttpWriter writer; private HttpWriter writer;
private Router<U> router; private Router<U> router;
private Locker<Context> logger;
public Client(Socket socket, Router<U> router) throws Exception{ public Client(Socket socket, Router<U> router) throws Exception{
this.reader = new HttpReader(socket); this.reader = new HttpReader(socket);
this.writer = new HttpWriter(socket); this.writer = new HttpWriter(socket);
this.router = router; this.router = router;
this.logger = router.getLogger();
} }
@Override @Override
@ -26,25 +24,28 @@ public class Client<U extends User> extends Thread{
reader.readHeaders(); reader.readHeaders();
RequestType type = RequestType.valueOf(headers[0]); RequestType type = RequestType.valueOf(headers[0]);
context = new Context(type, headers[1], isLogin(router, type, reader), writer, router.getDefaultHeaders(type)); context = new Context(type, headers[1], isLogin(type, reader), writer, router.getDefaultHeaders(type));
router.exec(context, reader, writer); router.exec(context, reader, writer);
writer.flush(); writer.flush();
writer.close(); writer.close();
}catch(InvalidJwtException e){ }catch(InvalidJwtException e){
}catch(Exception e){ this.router.getExceptionLogger().setValue(e);
e.printStackTrace(); }catch(Throwable e){
this.router.getExceptionLogger().setValue(e);
if(context != null && context.getResponseCode() == 0){ if(context != null && context.getResponseCode() == 0){
try{ try{
context.response(500); context.response(500);
writer.flush(); writer.flush();
writer.close(); writer.close();
}catch(Exception ex){} }catch(Exception ex){
this.router.getExceptionLogger().setValue(ex);
}
} }
} }
if(context != null) logger.setValue(context); if(context != null) router.getLogger().setValue(context);
} }
private User isLogin(Router<U> router, RequestType type, HttpReader reader) throws InvalidJwtException{ private User isLogin(RequestType type, HttpReader reader) throws InvalidJwtException{
String auth = reader.getHeader("Authorization"); String auth = reader.getHeader("Authorization");
if(auth == null) return null; if(auth == null) return null;
auth = auth.substring(7); auth = auth.substring(7);
@ -52,10 +53,12 @@ public class Client<U extends User> extends Thread{
return this.router.getUser(auth); return this.router.getUser(auth);
}catch(InvalidJwtException e){ }catch(InvalidJwtException e){
try{ try{
writer.response(401, router.getDefaultHeaders(type)); writer.response(401, this.router.getDefaultHeaders(type));
writer.flush(); writer.flush();
writer.close(); writer.close();
}catch(Exception ex){} }catch(Exception ex){
this.router.getExceptionLogger().setValue(ex);
}
throw e; throw e;
} }
} }

View file

@ -0,0 +1,70 @@
package dev.peerat.framework;
import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
public class DependencyInjector{
private Map<String, Object> map;
private List<BiFunction<Constructor<?>, Parameter, Object>> builders;
private Object[] injections;
public DependencyInjector(){
this.map = new HashMap<>();
this.builders = new ArrayList<>();
}
public DependencyInjector of(String name, Object value){
this.map.put(name, value);
return this;
}
public DependencyInjector of(BiFunction<Constructor<?>, Parameter, Object> builder){
this.builders.add(builder);
return this;
}
public DependencyInjector of(Object... injections){
if(this.injections == null){
this.injections = injections;
return this;
}
Object[] copy = new Object[this.injections.length+injections.length];
System.arraycopy(this.injections, 0, copy, 0, this.injections.length);
System.arraycopy(injections, 0, copy, this.injections.length, injections.length);
this.injections = copy;
return this;
}
Object applyDependency(Constructor<?> constructor, Parameter parameter, Map<Class<?>, Object> cache){
Injection annotation = parameter.getAnnotation(Injection.class);
if(annotation != null){
Object result = this.map.get(annotation.value());
if(result == null) throw new IllegalArgumentException("No depdency named "+annotation.value()+" ("+this.map.keySet()+") in constructor "+constructor);
return result;
}
for(BiFunction<Constructor<?>, Parameter, Object> function : builders){
Object result = function.apply(constructor, parameter);
if(result != null) return result;
}
if(this.injections == null) return null;
Class<?> type = parameter.getType();
Object result = null;
for(Object injection : injections){
if(type.isAssignableFrom(injection.getClass())){
if(cache.containsKey(type)){
throw new IllegalArgumentException("Double dependency for type "+type+", can be in constructor "+constructor);
}else{
cache.put(type, injection);
result = injection;
}
}
}
return result;
}
}

View file

@ -9,6 +9,7 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -52,6 +53,10 @@ public class HttpReader{
} }
} }
public Set<String> getHeaders(){
return this.headers.keySet();
}
public String getHeader(String key){ public String getHeader(String key){
return this.headers.get(key.toLowerCase()); return this.headers.get(key.toLowerCase());
} }

View file

@ -46,7 +46,7 @@ public class HttpWriter{
flush(); flush();
} }
private static String[] HEIGHTBITS = new String[9]; private static String[] HEIGHTBITS = new String[27];
private static String[] NINEBITS = new String[212]; private static String[] NINEBITS = new String[212];
static { static {
@ -59,6 +59,7 @@ public class HttpWriter{
HEIGHTBITS[6] = " Partial Content"; HEIGHTBITS[6] = " Partial Content";
HEIGHTBITS[7] = " Mutli-Status"; HEIGHTBITS[7] = " Mutli-Status";
HEIGHTBITS[8] = " Already Reported"; HEIGHTBITS[8] = " Already Reported";
HEIGHTBITS[26] = " IM Used";
NINEBITS[0] = " Multiple Choices"; NINEBITS[0] = " Multiple Choices";
NINEBITS[1] = " Moved Permanently"; NINEBITS[1] = " Moved Permanently";
@ -88,6 +89,8 @@ public class HttpWriter{
NINEBITS[116] = " Range Not Satisfiable"; NINEBITS[116] = " Range Not Satisfiable";
NINEBITS[117] = " Expectation Failed"; NINEBITS[117] = " Expectation Failed";
NINEBITS[118] = " I'm a Teapot"; NINEBITS[118] = " I'm a Teapot";
NINEBITS[119] = " Insufficient Space On Resource";
NINEBITS[120] = " Method Failure";
NINEBITS[121] = " Misdirected Request"; NINEBITS[121] = " Misdirected Request";
NINEBITS[122] = " Unprocessable Content"; NINEBITS[122] = " Unprocessable Content";
NINEBITS[123] = " Locked"; NINEBITS[123] = " Locked";
@ -108,6 +111,7 @@ public class HttpWriter{
NINEBITS[206] = " Variant Also Negotiates"; NINEBITS[206] = " Variant Also Negotiates";
NINEBITS[207] = " Insufficient Storage"; NINEBITS[207] = " Insufficient Storage";
NINEBITS[208] = " Loop Detected"; NINEBITS[208] = " Loop Detected";
NINEBITS[209] = " Bandwith Limit Exceeded";
NINEBITS[210] = " Not Extended"; NINEBITS[210] = " Not Extended";
NINEBITS[211] = " Network Authentication Required"; NINEBITS[211] = " Network Authentication Required";
} }

View file

@ -0,0 +1,11 @@
package dev.peerat.framework;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Injection{
String value();
}

View file

@ -8,8 +8,6 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
import dev.peerat.framework.Locker.Key;
public class Locker<V>{ public class Locker<V>{
private Map<Key, BlockingQueue<V>> map; private Map<Key, BlockingQueue<V>> map;

View file

@ -0,0 +1,10 @@
package dev.peerat.framework;
import java.lang.reflect.Method;
import java.util.regex.Matcher;
public interface RouteInterceptor{
boolean intercept(Matcher matcher, Context context, HttpReader reader, HttpWriter writer, Method method);
}

View file

@ -1,6 +1,8 @@
package dev.peerat.framework; package dev.peerat.framework;
import java.lang.reflect.Method;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -11,6 +13,7 @@ public class RouteMapper<U extends User>{
private Router<U> router; private Router<U> router;
private Response[] responses; private Response[] responses;
private Method[] methods;
private Route[] routes; private Route[] routes;
private Pattern[] patterns; private Pattern[] patterns;
private int[] calls; private int[] calls;
@ -19,13 +22,15 @@ public class RouteMapper<U extends User>{
public RouteMapper(Router<U> router){ public RouteMapper(Router<U> router){
this.router = router; this.router = router;
this.responses = new Response[0]; this.responses = new Response[0];
this.methods = new Method[0];
this.routes = new Route[0]; this.routes = new Route[0];
this.patterns = new Pattern[0]; this.patterns = new Pattern[0];
} }
public void register(Response response, Route route, Pattern pattern){ public void register(Response response, Method method, Route route, Pattern pattern){
int length = responses.length+1; int length = responses.length+1;
this.responses = addElement(responses, new Response[length], response); this.responses = addElement(responses, new Response[length], response);
this.methods = addElement(methods, new Method[length], method);
this.routes = addElement(routes, new Route[length], route); this.routes = addElement(routes, new Route[length], route);
this.patterns = addElement(patterns, new Pattern[length], pattern); this.patterns = addElement(patterns, new Pattern[length], pattern);
if(this.calls != null) this.calls = new int[length]; if(this.calls != null) this.calls = new int[length];
@ -36,15 +41,15 @@ public class RouteMapper<U extends User>{
this.dif = 2; this.dif = 2;
} }
public boolean exec(Context context, HttpReader reader, HttpWriter writer) throws Exception{ public boolean exec(Context context, HttpReader reader, HttpWriter writer, List<RouteInterceptor> interceptors) throws Exception{
Response result = null; Response response = null;
Method method = null;
Matcher matcher = null; Matcher matcher = null;
String path = context.getPath(); String path = context.getPath();
synchronized(responses){ synchronized(responses){
for(int i = 0; i < responses.length; i++){ for(int i = 0; i < responses.length; i++){
Response response = responses[i];
Route route = routes[i]; Route route = routes[i];
Pattern pattern = patterns[i]; Pattern pattern = patterns[i];
matcher = pattern.matcher(path); matcher = pattern.matcher(path);
@ -62,14 +67,18 @@ public class RouteMapper<U extends User>{
writer.response(401, router.getDefaultHeaders(context.getType())); writer.response(401, router.getDefaultHeaders(context.getType()));
return true; return true;
} }
response = responses[i];
method = methods[i];
order(i); order(i);
result = response;
break; break;
} }
} }
} }
if(result != null){ if(response != null){
result.exec(matcher, context, reader, writer); for(RouteInterceptor interceptor : interceptors){
if(!interceptor.intercept(matcher, context, reader, writer, method)) return true;
}
response.exec(matcher, context, reader, writer);
return true; return true;
} }
return false; return false;
@ -86,6 +95,7 @@ public class RouteMapper<U extends User>{
if(index < 1) return; if(index < 1) return;
if(call > this.calls[index-1]){ if(call > this.calls[index-1]){
switchElement(responses, index, index-1); switchElement(responses, index, index-1);
switchElement(methods, index, index-1);
switchElement(routes, index, index-1); switchElement(routes, index, index-1);
switchElement(patterns, index, index-1); switchElement(patterns, index, index-1);

View file

@ -1,8 +1,18 @@
package dev.peerat.framework; package dev.peerat.framework;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.security.Key;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -11,6 +21,7 @@ import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory; import javax.net.ssl.SSLServerSocketFactory;
import org.jose4j.jwa.AlgorithmConstraints.ConstraintType; import org.jose4j.jwa.AlgorithmConstraints.ConstraintType;
import org.jose4j.jwk.JsonWebKey.OutputControlLevel;
import org.jose4j.jwk.RsaJsonWebKey; import org.jose4j.jwk.RsaJsonWebKey;
import org.jose4j.jwk.RsaJwkGenerator; import org.jose4j.jwk.RsaJwkGenerator;
import org.jose4j.jws.AlgorithmIdentifiers; import org.jose4j.jws.AlgorithmIdentifiers;
@ -28,7 +39,9 @@ public class Router<U extends User>{
} }
private Locker<Context> logger; private Locker<Context> logger;
private Locker<Throwable> exceptions;
private RouteMapper<U>[] mappers; private RouteMapper<U>[] mappers;
private List<RouteInterceptor> interceptors;
private Response noFileFound; private Response noFileFound;
private RsaJsonWebKey rsaJsonWebKey; private RsaJsonWebKey rsaJsonWebKey;
private JwtConsumer jwtConsumer; private JwtConsumer jwtConsumer;
@ -37,30 +50,46 @@ public class Router<U extends User>{
private String[][] headers; private String[][] headers;
private ServerSocket serverSocket; private ServerSocket serverSocket;
public Router() throws Exception{ public Router(){
this.logger = new Locker<>(); this.logger = new Locker<>();
this.exceptions = new Locker<>();
int types = RequestType.values().length; int types = RequestType.values().length;
this.mappers = new RouteMapper[types]; this.mappers = new RouteMapper[types];
this.interceptors = new ArrayList<>();
for(RequestType type : RequestType.values()) this.mappers[type.ordinal()] = new RouteMapper<>(this); for(RequestType type : RequestType.values()) this.mappers[type.ordinal()] = new RouteMapper<>(this);
this.rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
this.headers = new String[types][0]; this.headers = new String[types][0];
} }
public Router<U> configureJwt(Consumer<JwtConsumerBuilder> consumer, Consumer<JwtClaims> claims, Function<JwtClaims, U> userCreator){ public Router<U> configureJwt(Consumer<JwtConsumerBuilder> consumer, Consumer<JwtClaims> claims, Function<JwtClaims, U> userCreator) throws Exception{
JwtConsumerBuilder builder = new JwtConsumerBuilder() this.rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
.setRequireExpirationTime() configureJwtWithKey(consumer, claims, userCreator, this.rsaJsonWebKey.getKey());
.setAllowedClockSkewInSeconds(30)
.setVerificationKey(rsaJsonWebKey.getKey())
.setJwsAlgorithmConstraints(ConstraintType.PERMIT, AlgorithmIdentifiers.RSA_USING_SHA256);
consumer.accept(builder);
this.jwtConsumer = builder.build();
this.claims = claims;
this.userCreator = userCreator;
return this; return this;
} }
public Router<U> configureJwt(Consumer<JwtConsumerBuilder> consumer, Consumer<JwtClaims> claims, Function<JwtClaims, U> userCreator, Map<String, Object> keyParams) throws Exception{
this.rsaJsonWebKey = new RsaJsonWebKey(keyParams);
configureJwtWithKey(consumer, claims, userCreator, this.rsaJsonWebKey.getKey());
return this;
}
private void configureJwtWithKey(Consumer<JwtConsumerBuilder> consumer, Consumer<JwtClaims> claims, Function<JwtClaims, U> userCreator, Key key) throws Exception{
JwtConsumerBuilder builder = new JwtConsumerBuilder()
.setRequireExpirationTime()
.setAllowedClockSkewInSeconds(30)
.setVerificationKey(key)
.setJwsAlgorithmConstraints(ConstraintType.PERMIT, AlgorithmIdentifiers.RSA_USING_SHA256);
consumer.accept(builder);
this.jwtConsumer = builder.build();
this.claims = claims;
this.userCreator = userCreator;
}
public Map<String, Object> exportJwtKey(){
return this.rsaJsonWebKey.toParams(OutputControlLevel.INCLUDE_PRIVATE);
}
public Router<U> addDefaultHeaders(RequestType type, String... headers){ public Router<U> addDefaultHeaders(RequestType type, String... headers){
String[] origin = this.headers[type.ordinal()]; String[] origin = this.headers[type.ordinal()];
String[] copy = new String[origin.length+headers.length]; String[] copy = new String[origin.length+headers.length];
@ -76,18 +105,84 @@ public class Router<U extends User>{
Response.class.getDeclaredMethods()[0].getParameterTypes()); Response.class.getDeclaredMethods()[0].getParameterTypes());
Route route = method.getAnnotation(Route.class); Route route = method.getAnnotation(Route.class);
this.mappers[route.type().ordinal()].register(response, route, Pattern.compile(route.path())); this.mappers[route.type().ordinal()].register(response, method, route, Pattern.compile(route.path()));
}catch(Exception e){ }catch(Exception e){
throw new IllegalArgumentException(e); throw new IllegalArgumentException(e);
} }
return this; return this;
} }
public Router<U> registerPackages(Object... injections){
return registerPackages(new DependencyInjector().of(injections));
}
public Router<U> registerPackages(DependencyInjector injector){
String clazz = Thread.currentThread().getStackTrace()[2].getClassName();
String pack = clazz.substring(0, clazz.lastIndexOf('.'));
return registerPackages(pack, injector);
}
public Router<U> registerPackages(String name, Object... injections){
return registerPackages(name, new DependencyInjector().of(injections));
}
public Router<U> registerPackages(String name, DependencyInjector injector){
InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream(name.replace(".", "/"));
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;
Map<Class<?>, Object> cache = new HashMap<>();
while((line = reader.readLine()) != null){
if(line.endsWith(".class")){
Class<?> clazz = Class.forName(name+"."+line.substring(0, line.lastIndexOf('.')));
if(Response.class.isAssignableFrom(clazz)){
if(clazz.equals(Response.class)) continue;
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
if(constructors.length != 1) continue;
injectDependencies(constructors[0], cache, injector);
}
}else{
registerPackages(name+"."+line, injector);
}
}
reader.close();
}catch(Exception e){
System.err.println("Failed to read "+name);
e.printStackTrace();
}
return this;
}
private void injectDependencies(Constructor<?> constructor, Map<Class<?>, Object> cache, DependencyInjector injector){
Parameter[] parameters = constructor.getParameters();
Object[] injections = new Object[parameters.length];
for(int i = 0; i < parameters.length; i++){
Parameter parameter = parameters[i];
Class<?> type = parameter.getType();
Object dependency = cache.get(type);
if(dependency != null) injections[i] = dependency;
else if((injections[i] = injector.applyDependency(constructor, parameter, cache)) == null) throw new IllegalArgumentException("No dependency for type "+type+" in constructor "+constructor);
}
try {
Response response = (Response) constructor.newInstance(injections);
register(response);
System.out.println("registerd "+response.getClass());
} catch (Exception e){
e.printStackTrace();
}
}
public Router<U> setDefault(Response response){ public Router<U> setDefault(Response response){
this.noFileFound = response; this.noFileFound = response;
return this; return this;
} }
public Router<U> addInterceptor(RouteInterceptor interceptor){
this.interceptors.add(interceptor);
return this;
}
public Router<U> activeReOrdering(){ public Router<U> activeReOrdering(){
for(RouteMapper<?> mapper : this.mappers) mapper.activeReOrdering(); for(RouteMapper<?> mapper : this.mappers) mapper.activeReOrdering();
return this; return this;
@ -98,7 +193,7 @@ public class Router<U extends User>{
} }
void exec(Context context, HttpReader reader, HttpWriter writer) throws Exception{ void exec(Context context, HttpReader reader, HttpWriter writer) throws Exception{
if(this.mappers[context.getType().ordinal()].exec(context, reader, writer)) return; if(this.mappers[context.getType().ordinal()].exec(context, reader, writer, this.interceptors)) return;
if(noFileFound != null) noFileFound.exec(null, context, reader, writer); if(noFileFound != null) noFileFound.exec(null, context, reader, writer);
} }
@ -133,6 +228,10 @@ public class Router<U extends User>{
return this.logger; return this.logger;
} }
public Locker<Throwable> getExceptionLogger(){
return this.exceptions;
}
public void listen(int port, boolean ssl) throws Exception{ public void listen(int port, boolean ssl) throws Exception{
if (ssl) { // Not needed with the use of a proxy if (ssl) { // Not needed with the use of a proxy
try { try {

View file

@ -45,7 +45,11 @@ public class JsonParser extends Parser<Json>{
content.then(new RedirectStateTree<>(base, (global, local) -> global.set(local.get()))).end(); content.then(new RedirectStateTree<>(base, (global, local) -> global.set(local.get()))).end();
content.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.STRING), (bag, token) -> bag.set(token))).end(); content.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.STRING), (bag, token) -> bag.set(token))).end();
content.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.CHAR), (bag, token) -> bag.set(token))).end(); content.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.CHAR), (bag, token) -> bag.set(token))).end();
content.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.NAME), (bag, token) -> bag.set(token))).end(); StateTree<Json> number = content.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.NAME), (bag, token) -> bag.set(token)));
number.end();
number.then((validator) -> validator.validate((token) -> token.getValue().equals("."), (bag, token) -> bag.set(bag.<Token>get().concat(token))))
.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.NAME), (bag, token) -> bag.set(bag.<Token>get().concat(token))))
.end();
StateTree<Json> mapper = new StateTree<>(); StateTree<Json> mapper = new StateTree<>();
StateTree<Json> mapper_key = mapper.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.STRING), (bag, token) -> { StateTree<Json> mapper_key = mapper.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.STRING), (bag, token) -> {
@ -110,10 +114,10 @@ public class JsonParser extends Parser<Json>{
return Long.parseLong(content); return Long.parseLong(content);
}catch(Exception _){ }catch(Exception _){
try { try {
return Boolean.parseBoolean(content); return Double.parseDouble(content);
}catch(Exception __){ }catch(Exception __){
try{ try{
return Double.parseDouble(content); return Boolean.parseBoolean(content);
}catch(Exception ___){} }catch(Exception ___){}
} }
} }

View file

@ -5,7 +5,7 @@ import be.jeffcheasey88.peeratcode.parser.TokenType;
import be.jeffcheasey88.peeratcode.parser.Tokenizer; import be.jeffcheasey88.peeratcode.parser.Tokenizer;
public class JsonTokenizer extends Tokenizer{ public class JsonTokenizer extends Tokenizer{
@Override @Override
public void parse(String line){ public void parse(String line){
for(int i = 0; i < line.length(); i++){ for(int i = 0; i < line.length(); i++){
@ -29,7 +29,22 @@ public class JsonTokenizer extends Tokenizer{
for(; j < line.length(); j++){ for(; j < line.length(); j++){
c = line.charAt(j); c = line.charAt(j);
if(c == '\\'){ if(c == '\\'){
buffer+=c+line.charAt(++j); c = line.charAt(++j);
switch(c){
case 'n':
buffer+='\n';
break;
case 'r':
buffer+='\r';
break;
case 't':
buffer+='\t';
break;
default:
buffer+=c;
break;
}
continue;
} }
if(c == '\"') break; if(c == '\"') break;
buffer+=c; buffer+=c;
@ -38,21 +53,6 @@ public class JsonTokenizer extends Tokenizer{
i=j; i=j;
continue; continue;
} }
if(c == '\''){
String buffer = "";
int j = i+1;
for(; j < line.length(); j++){
c = line.charAt(j);
if(c == '\\'){
buffer+=c+line.charAt(++j);
}
if(c == '\'') break;
buffer+=c;
}
getTokens().add(new Token(1, i+1, buffer, TokenType.CHAR));
i=j;
continue;
}
getTokens().add(new Token(1, i+1, ""+c, TokenType.DELIMITER)); getTokens().add(new Token(1, i+1, ""+c, TokenType.DELIMITER));
} }
} }