Working on generalizing the serializers

This commit is contained in:
Norbi Peti 2016-08-09 12:12:46 +02:00
parent 88733223c6
commit d6834c2ae4
9 changed files with 82 additions and 36 deletions

View file

@ -4,6 +4,11 @@
$(document).ready(function () {
var cmsgs = document.getElementById("channelmessages");
if (cmsgs != null && cmsgs.childElementCount > 0)
if (cmsgs != null && cmsgs.childElementCount > 0) {
cmsgs.forEach(function (item) {
var ctime = item.getElementById("converttime");
ctime.innerText = new Date(ctime.innerText * 1).toDateString();
});
cmsgs.lastElementChild.scrollIntoView(false);
}
});

View file

@ -16,9 +16,9 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.sun.net.httpserver.HttpServer;
import io.github.norbipeti.chat.server.data.*;
import io.github.norbipeti.chat.server.db.domain.*;
import io.github.norbipeti.chat.server.io.DataType;
import io.github.norbipeti.chat.server.page.*;
public class Main {
@ -31,12 +31,17 @@ public class Main {
LogManager.getLogger().log(Level.INFO, "Loading files...");
DataManager.init();
final GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(new TypeToken<LoaderCollection<Conversation>>() {
}.getType(), new LoaderCollectionSerializer<Conversation>());
gsonBuilder.registerTypeAdapter(new TypeToken<LoaderCollection<MessageChunk>>() {
}.getType(), new LoaderCollectionSerializer<MessageChunk>());
gsonBuilder.registerTypeAdapter(new TypeToken<LoaderCollection<User>>() {
}.getType(), new LoaderCollectionSerializer<User>());
Reflections rf = new Reflections(
new ConfigurationBuilder().setUrls(ClasspathHelper.forClassLoader(SavedData.class.getClassLoader()))
.addClassLoader(SavedData.class.getClassLoader()).addScanners(new SubTypesScanner())
.filterInputsBy((String pkg) -> pkg.contains(SavedData.class.getPackage().getName())));
Set<Class<? extends SavedData>> datas = rf.getSubTypesOf(SavedData.class);
for (Class<? extends SavedData> data : datas) {
if (Modifier.isAbstract(data.getModifiers()))
continue;
gsonBuilder.registerTypeAdapter(new DataType(LoaderCollection.class, data),
new LoaderCollectionSerializer()); // TODO: Test
}
gsonBuilder.registerTypeAdapter(new TypeToken<LoaderRef<Conversation>>() {
}.getType(), new LoaderRefSerializer<Conversation>());
gsonBuilder.registerTypeAdapter(new TypeToken<LoaderRef<MessageChunk>>() {
@ -58,10 +63,10 @@ public class Main {
*/
LogManager.getLogger().log(Level.INFO, "Starting webserver..."); // TODO: Separate IDs for conversations and users
HttpServer server = HttpServer.create(new InetSocketAddress(InetAddress.getLocalHost(), 8080), 10);
Reflections rf = new Reflections(
rf = new Reflections(
new ConfigurationBuilder().setUrls(ClasspathHelper.forClassLoader(Page.class.getClassLoader()))
.addClassLoader(Page.class.getClassLoader()).addScanners(new SubTypesScanner())
.filterInputsBy((String pkg) -> pkg.contains("io.github.norbipeti.chat.server.page")));
.filterInputsBy((String pkg) -> pkg.contains(Page.class.getPackage().getName())));
Set<Class<? extends Page>> pages = rf.getSubTypesOf(Page.class);
for (Class<? extends Page> page : pages) {
try {

View file

@ -61,7 +61,7 @@ public final class DataManager {
private static <T extends SavedData> T loadFromFile(File file, Class<T> cl) {
try {
if (!file.exists()) {
T obj = cl.newInstance();
T obj = SavedData.create(cl);
return obj;
}
if (cache.containsKey(file))
@ -146,7 +146,7 @@ public final class DataManager {
File file = new File("data", "idlist.ini");
String contents = "";
for (Entry<Class<? extends SavedData>, Long> item : ids.entrySet()) {
contents += item.getKey().getName() + "=" + item.getValue() + "\n";
contents += item.getKey().getSimpleName() + "=" + item.getValue() + "\n";
}
Files.write(contents, file, StandardCharsets.UTF_8);
} catch (Exception e) {

View file

@ -22,7 +22,7 @@ import io.github.norbipeti.chat.server.db.domain.SavedData;
*
* @param <T>
*/
public class LoaderCollection<T extends SavedData> implements List<T>, Serializable {
public class LoaderCollection<T extends SavedData> extends Loader implements List<T> {
private static final long serialVersionUID = 5426152406394894301L;
List<Long> idlist;
Class<T> cl;
@ -32,6 +32,7 @@ public class LoaderCollection<T extends SavedData> implements List<T>, Serializa
*/
@Deprecated
public LoaderCollection() {
idlist = new ArrayList<>();
}
public LoaderCollection(Class<T> cl) {

View file

@ -1,6 +1,8 @@
package io.github.norbipeti.chat.server.data;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;
@ -15,15 +17,16 @@ import io.github.norbipeti.chat.server.db.domain.SavedData;
// @SuppressWarnings("rawtypes")
public class LoaderCollectionSerializer extends TypeAdapter<LoaderCollection<?>> {
private static final Type returnType = getReturnType();
// private static final Type returnType = getReturnType();
// TODO: http://stackoverflow.com/a/17300227
@Override
public void write(JsonWriter out, LoaderCollection<?> value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
out.beginObject(); // TODO: http://stackoverflow.com/a/17300227
out.beginObject();
out.name("items");
new Gson().toJson(value.idlist, new TypeToken<List<Long>>() {
}.getType(), out);
@ -33,7 +36,7 @@ public class LoaderCollectionSerializer extends TypeAdapter<LoaderCollection<?>>
@SuppressWarnings("unchecked")
@Override
public LoaderCollection<T> read(JsonReader in) throws IOException {
public LoaderCollection<? extends SavedData> read(JsonReader in) throws IOException {
if (in.peek().equals(JsonToken.NULL)) {
in.nextNull();
return null;
@ -46,25 +49,27 @@ public class LoaderCollectionSerializer extends TypeAdapter<LoaderCollection<?>>
new Exception("Error: Next isn't \"class\"").printStackTrace();
return null;
}
Class<T> cl;
Class<? extends SavedData> cl;
try {
cl = (Class<T>) Class.forName(DataManager.getPackageName() + "." + in.nextString());
cl = (Class<? extends SavedData>) Class.forName(DataManager.getPackageName() + "." + in.nextString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
LoaderCollection<T> col = new LoaderCollection<T>(cl);
LoaderCollection<? extends SavedData> col;
try {
col = LoaderCollection.class.getDeclaredConstructor(Class.class).newInstance(cl);
} catch (Exception e) {
e.printStackTrace();
return null;
}
col.idlist.addAll(list);
in.endObject();
return col;
}
private static Type getReturnType() {
try {
return LoaderCollection.class.getDeclaredMethod("get", Integer.class).getGenericReturnType();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/*
* private static Type getReturnType() { try { for (Method m : LoaderCollection.class.getDeclaredMethods()) System.out.println(m); return LoaderCollection.class.getDeclaredMethod("get",
* int.class).getGenericReturnType(); } catch (Exception e) { e.printStackTrace(); } return null; }
*/
}

View file

@ -6,19 +6,16 @@ import io.github.norbipeti.chat.server.db.domain.SavedData;
/**
* <p>
* This class will only store IDs and load the object when calling
* {@link #get()}
* This class will only store IDs and load the object when calling {@link #get()}
* </p>
* <p>
* And will also only save IDs when serialized with {@link LoaderRefSerializer}
* </p>
*
* @author Norbi
*
* @param <T>
* The type of the stored object
* @param <T> The type of the stored object
*/
public class LoaderRef<T extends SavedData> implements Serializable {
public class LoaderRef<T extends SavedData> extends Loader {
private static final long serialVersionUID = 8458570738734235320L;
Class<T> cl;
Long id;

View file

@ -36,7 +36,7 @@ public class LoaderRefSerializer<T extends SavedData> extends TypeAdapter<Loader
in.nextName();
long id = in.nextLong();
if (!in.nextName().equals("class")) {
new Exception("Error: Next isn't \"class\"").printStackTrace();
new Exception("Error: Next isn't \"class\"").printStackTrace(); // TODO: Same as at LoaderCollectionSerializer
return null;
}
Class<T> cl;

View file

@ -0,0 +1,32 @@
package io.github.norbipeti.chat.server.io;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import io.github.norbipeti.chat.server.data.Loader;
import io.github.norbipeti.chat.server.db.domain.SavedData;
public final class DataType implements ParameterizedType {
private Class<? extends SavedData> datacl;
private Class<? extends Loader> loadercl;
public DataType(Class<? extends Loader> loadercl, Class<? extends SavedData> datacl) {
this.datacl = datacl;
this.loadercl = loadercl;
}
@Override
public Type[] getActualTypeArguments() {
return new Type[] { datacl };
}
@Override
public Type getRawType() {
return loadercl;
}
@Override
public Type getOwnerType() {
return null;
}
}

View file

@ -61,9 +61,10 @@ public class IndexPage extends Page {
for (Message message : chunk.getMessages()) {
Element msgelement = channelmessages.appendElement("div");
Element header = msgelement.appendElement("p");
header.text(message.getSender().get().getName() + " - " + message.getTime());
header.text(message.getSender().get().getName() + " - <span id=\"converttime\">"
+ message.getTime().getTime() + "</span>");
Element body = msgelement.appendElement("p");
body.text(message.getMessage());
body.text(message.getMessage()); // TODO: Use JavaScript to convert time
}
}
return doc;