Message listener in progress with a refactoring still
This commit is contained in:
parent
b81f1b2a81
commit
319a2a9aa1
6
pom.xml
6
pom.xml
|
@ -100,6 +100,12 @@
|
|||
<artifactId>gson</artifactId>
|
||||
<version>2.7</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/io.vertx/vertx-core -->
|
||||
<dependency>
|
||||
<groupId>io.vertx</groupId>
|
||||
<artifactId>vertx-core</artifactId>
|
||||
<version>3.3.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
|
|
|
@ -19,6 +19,8 @@ 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.*;
|
||||
import io.vertx.core.Vertx;
|
||||
import io.vertx.core.http.HttpServerOptions;
|
||||
|
||||
public class Main {
|
||||
public static Gson gson;
|
||||
|
@ -30,10 +32,10 @@ public class Main {
|
|||
LogManager.getLogger().log(Level.INFO, "Loading files...");
|
||||
DataManager.init();
|
||||
final GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
Reflections rf = new Reflections(
|
||||
new ConfigurationBuilder().setUrls(ClasspathHelper.forClassLoader(ManagedData.class.getClassLoader()))
|
||||
.addClassLoader(ManagedData.class.getClassLoader()).addScanners(new SubTypesScanner())
|
||||
.filterInputsBy((String pkg) -> pkg.contains(ManagedData.class.getPackage().getName())));
|
||||
Reflections rf = new Reflections(new ConfigurationBuilder()
|
||||
.setUrls(ClasspathHelper.forClassLoader(ManagedData.class.getClassLoader()))
|
||||
.addClassLoader(ManagedData.class.getClassLoader()).addScanners(new SubTypesScanner())
|
||||
.filterInputsBy((String pkg) -> pkg.contains(ManagedData.class.getPackage().getName())));
|
||||
Set<Class<? extends ManagedData>> datas = rf.getSubTypesOf(ManagedData.class);
|
||||
for (Class<? extends ManagedData> data : datas) {
|
||||
if (Modifier.isAbstract(data.getModifiers()))
|
||||
|
@ -75,6 +77,13 @@ public class Main {
|
|||
}
|
||||
}
|
||||
server.start();
|
||||
LogManager.getLogger().info("Starting websocket server...");
|
||||
Vertx vertx = Vertx.vertx();
|
||||
io.vertx.core.http.HttpServer socketserver = vertx.createHttpServer();
|
||||
socketserver.websocketHandler(websocket -> {
|
||||
websocket.writeFinalTextFrame("Hello"); // TODO
|
||||
});
|
||||
socketserver.listen(8180);
|
||||
LogManager.getLogger().log(Level.INFO, "Ready... Press Enter to stop.");
|
||||
System.in.read();
|
||||
LogManager.getLogger().log(Level.INFO, "Stopping...");
|
||||
|
|
|
@ -12,7 +12,7 @@ import java.util.Map.Entry;
|
|||
|
||||
import com.google.common.io.Files;
|
||||
import io.github.norbipeti.chat.server.Main;
|
||||
import io.github.norbipeti.chat.server.db.domain.ManagedData;
|
||||
import io.github.norbipeti.chat.server.db.domain.SavedData;
|
||||
|
||||
public final class DataManager {
|
||||
private DataManager() {
|
||||
|
@ -20,7 +20,7 @@ public final class DataManager {
|
|||
|
||||
private static final File datafolder = new File("data");
|
||||
|
||||
public static <T extends ManagedData> void save(T object) {
|
||||
public static <T extends SavedData> void save(T object) {
|
||||
try {
|
||||
File file = new File(datafolder, getFileName(object.getClass(), object.getId()));
|
||||
cache.put(file, object);
|
||||
|
@ -30,11 +30,11 @@ public final class DataManager {
|
|||
}
|
||||
}
|
||||
|
||||
public static <T extends ManagedData> T load(Class<T> cl, long id) {
|
||||
public static <T extends SavedData> T load(Class<T> cl, long id) {
|
||||
return loadFromFile(new File(datafolder, getFileName(cl, id)), cl);
|
||||
}
|
||||
|
||||
public static <T extends ManagedData> LoaderCollection<T> getAll(Class<T> cl) {
|
||||
public static <T extends SavedData> LoaderCollection<T> getAll(Class<T> cl) {
|
||||
String[] filenames = datafolder.list(new FilenameFilter() {
|
||||
|
||||
@Override
|
||||
|
@ -59,10 +59,10 @@ public final class DataManager {
|
|||
// TODO: Handle unloading of used objects (prevent detached objects)
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends ManagedData> T loadFromFile(File file, Class<T> cl) {
|
||||
private static <T extends SavedData> T loadFromFile(File file, Class<T> cl) {
|
||||
try {
|
||||
if (!file.exists()) {
|
||||
T obj = ManagedData.create(cl);
|
||||
T obj = SavedData.create(cl);
|
||||
return obj;
|
||||
}
|
||||
if (cache.containsKey(file))
|
||||
|
@ -83,18 +83,18 @@ public final class DataManager {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static <T extends ManagedData> boolean remove(T obj) {
|
||||
public static <T extends SavedData> boolean remove(T obj) {
|
||||
if (cache.containsValue(obj))
|
||||
cache.values().remove(obj);
|
||||
return new File(obj.getClass().getSimpleName() + "-" + obj.getId()).delete();
|
||||
}
|
||||
|
||||
public static <T extends ManagedData> boolean remove(Class<T> cl, Long id) {
|
||||
public static <T extends SavedData> boolean remove(Class<T> cl, Long id) {
|
||||
return new File(cl.getName() + "-" + id).delete();
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
packagename = ManagedData.class.getPackage().getName();
|
||||
packagename = SavedData.class.getPackage().getName();
|
||||
datafolder.mkdir();
|
||||
nextids = loadNextIDs();
|
||||
}
|
||||
|
@ -108,32 +108,32 @@ public final class DataManager {
|
|||
public static void save() {
|
||||
saveNextIDs(nextids);
|
||||
for (Entry<File, Object> item : cache.entrySet()) {
|
||||
DataManager.save((ManagedData) item.getValue());
|
||||
DataManager.save((SavedData) item.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private static HashMap<Class<? extends ManagedData>, Long> nextids;
|
||||
private static HashMap<Class<? extends SavedData>, Long> nextids;
|
||||
|
||||
public static Map<Class<? extends ManagedData>, Long> getNextIDs() {
|
||||
public static Map<Class<? extends SavedData>, Long> getNextIDs() {
|
||||
return Collections.unmodifiableMap(nextids);
|
||||
}
|
||||
|
||||
public static void setNextID(Class<? extends ManagedData> cl, Long id) {
|
||||
public static void setNextID(Class<? extends SavedData> cl, Long id) {
|
||||
nextids.put(cl, id);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static HashMap<Class<? extends ManagedData>, Long> loadNextIDs() {
|
||||
private static HashMap<Class<? extends SavedData>, Long> loadNextIDs() {
|
||||
try {
|
||||
File file = new File("data", "idlist.ini");
|
||||
if (!file.exists())
|
||||
return new HashMap<>();
|
||||
BufferedReader reader = Files.newReader(file, StandardCharsets.UTF_8);
|
||||
String line;
|
||||
HashMap<Class<? extends ManagedData>, Long> ret = new HashMap<>();
|
||||
HashMap<Class<? extends SavedData>, Long> ret = new HashMap<>();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
String[] spl = line.split("\\=");
|
||||
ret.put((Class<? extends ManagedData>) Class.forName(packagename + "." + spl[0]), Long.parseLong(spl[1]));
|
||||
ret.put((Class<? extends SavedData>) Class.forName(packagename + "." + spl[0]), Long.parseLong(spl[1]));
|
||||
}
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
|
@ -142,11 +142,11 @@ public final class DataManager {
|
|||
return new HashMap<>();
|
||||
}
|
||||
|
||||
private static void saveNextIDs(HashMap<Class<? extends ManagedData>, Long> ids) {
|
||||
private static void saveNextIDs(HashMap<Class<? extends SavedData>, Long> ids) {
|
||||
try {
|
||||
File file = new File("data", "idlist.ini");
|
||||
String contents = "";
|
||||
for (Entry<Class<? extends ManagedData>, Long> item : ids.entrySet()) {
|
||||
for (Entry<Class<? extends SavedData>, Long> item : ids.entrySet()) {
|
||||
contents += item.getKey().getSimpleName() + "=" + item.getValue() + "\n";
|
||||
}
|
||||
Files.write(contents, file, StandardCharsets.UTF_8);
|
||||
|
@ -155,7 +155,7 @@ public final class DataManager {
|
|||
}
|
||||
}
|
||||
|
||||
private static <T extends ManagedData> String getFileName(Class<T> cl, Long id) {
|
||||
private static <T extends SavedData> String getFileName(Class<T> cl, Long id) {
|
||||
if (id != null)
|
||||
return cl.getSimpleName() + "-" + id + ".json";
|
||||
else
|
||||
|
|
|
@ -6,7 +6,7 @@ import io.github.norbipeti.chat.server.data.LoaderCollection;
|
|||
|
||||
@Entity
|
||||
@Table(name = "CONVERSATION")
|
||||
public class Conversation extends ManagedData {
|
||||
public class Conversation extends SavedData {
|
||||
private static final long serialVersionUID = 5058682475353799722L;
|
||||
// @Id
|
||||
// @GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
|
@ -46,7 +46,7 @@ public class Conversation extends ManagedData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setId(long id) {
|
||||
protected void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,14 +9,14 @@ import io.github.norbipeti.chat.server.data.DataManager;
|
|||
public abstract class ManagedData implements Serializable {
|
||||
public abstract long getId();
|
||||
|
||||
public abstract void setId(long id);
|
||||
protected abstract void setId(long id);
|
||||
|
||||
protected abstract void init();
|
||||
|
||||
protected ManagedData() {
|
||||
}
|
||||
|
||||
static <T extends ManagedData> T create(Class<T> cl) {
|
||||
public static <T extends ManagedData> T create(Class<T> cl) {
|
||||
T obj;
|
||||
try {
|
||||
Constructor<T> constructor = cl.getDeclaredConstructor(new Class<?>[0]);
|
||||
|
|
|
@ -9,7 +9,7 @@ import io.github.norbipeti.chat.server.data.LoaderRef;
|
|||
|
||||
@Entity
|
||||
@Table(name = "MESSAGE")
|
||||
public class Message implements Serializable {
|
||||
public class Message extends ManagedData {
|
||||
private static final int MESSAGE_LIMIT_PER_CHUNK = 50;
|
||||
private static final long serialVersionUID = 6345941601716826570L;
|
||||
private static Long nextid = 0L;
|
||||
|
@ -58,27 +58,16 @@ public class Message implements Serializable {
|
|||
return messagechunk;
|
||||
}
|
||||
|
||||
public void setMessageChunk(LoaderRef<MessageChunk> messagechunk) {
|
||||
this.messagechunk = messagechunk;
|
||||
public void setConversation(LoaderRef<Conversation> conversation) {
|
||||
setConv(conversation.get());
|
||||
}
|
||||
|
||||
public void setMessageChunk(MessageChunk messagechunk) {
|
||||
this.messagechunk = new LoaderRef<MessageChunk>(messagechunk);
|
||||
public void setConversation(Conversation conversation) {
|
||||
setConv(conversation);
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
private Message() {
|
||||
}
|
||||
|
||||
public static Message create(Conversation parent) {
|
||||
Message msg = new Message();
|
||||
private void setConv(Conversation parent) {
|
||||
Message msg = this;
|
||||
int size = parent.getMesssageChunks().size();
|
||||
MessageChunk chunk;
|
||||
if (size == 0 || parent.getMesssageChunks().get(size - 1).getMessages().size() >= MESSAGE_LIMIT_PER_CHUNK) {
|
||||
|
@ -87,7 +76,21 @@ public class Message implements Serializable {
|
|||
parent.getMesssageChunks().add(chunk);
|
||||
} else
|
||||
chunk = parent.getMesssageChunks().get(size - 1);
|
||||
msg.setMessageChunk(chunk);
|
||||
return msg;
|
||||
msg.messagechunk = new LoaderRef<MessageChunk>(chunk);
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
protected void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
private Message() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.List;
|
|||
|
||||
import io.github.norbipeti.chat.server.data.LoaderRef;
|
||||
|
||||
public class MessageChunk extends ManagedData {
|
||||
public class MessageChunk extends SavedData {
|
||||
private static final long serialVersionUID = -1665300779209348467L;
|
||||
|
||||
private Long id;
|
||||
|
@ -39,10 +39,14 @@ public class MessageChunk extends ManagedData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setId(long id) {
|
||||
protected void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
private MessageChunk() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package io.github.norbipeti.chat.server.db.domain;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class SavedData extends ManagedData {
|
||||
|
||||
}
|
|
@ -9,7 +9,7 @@ import io.github.norbipeti.chat.server.data.LoaderCollection;
|
|||
|
||||
@Entity
|
||||
@Table(name = "\"USER\"")
|
||||
public class User extends ManagedData {
|
||||
public class User extends SavedData {
|
||||
private static final long serialVersionUID = 2862762084164225666L;
|
||||
private Long id;
|
||||
private String name;
|
||||
|
@ -105,11 +105,11 @@ public class User extends ManagedData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setId(long id) {
|
||||
protected void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static User createUser() {
|
||||
return ManagedData.create(User.class);
|
||||
@Override
|
||||
public void init() {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public class IndexPage extends Page {
|
|||
if (user.getConversations().size() == 0) {
|
||||
LoaderCollection<Conversation> convs = DataManager.getAll(Conversation.class);
|
||||
if (convs.size() == 0) {
|
||||
Conversation c = Conversation.create();
|
||||
Conversation c = ManagedData.create(Conversation.class);
|
||||
convs.add(c); // TODO: Handle no conversation open
|
||||
}
|
||||
user.getConversations().add(convs.get(0));
|
||||
|
|
|
@ -7,6 +7,7 @@ import org.apache.logging.log4j.LogManager;
|
|||
import com.google.gson.JsonObject;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
|
||||
import io.github.norbipeti.chat.server.Main;
|
||||
import io.github.norbipeti.chat.server.data.DataManager;
|
||||
import io.github.norbipeti.chat.server.data.LoaderCollection;
|
||||
import io.github.norbipeti.chat.server.db.domain.Conversation;
|
||||
|
@ -18,6 +19,7 @@ import io.github.norbipeti.chat.server.io.IOHelper;
|
|||
|
||||
public class ReceiveMessageAjaxPage extends Page {
|
||||
// http://stackoverflow.com/questions/9242404/javascript-listen-to-server
|
||||
// https://techoctave.com/c7/posts/60-simple-long-polling-example-with-javascript-and-jquery
|
||||
@Override
|
||||
public String GetName() {
|
||||
return "receivemessage";
|
||||
|
@ -30,40 +32,16 @@ public class ReceiveMessageAjaxPage extends Page {
|
|||
IOHelper.SendResponse(403, "<p>Please log in to receive messages</p>", exchange);
|
||||
return;
|
||||
}
|
||||
JsonObject obj = new JsonObject();
|
||||
String message = obj.get("message").getAsString().trim();
|
||||
int conversation = obj.get("conversation").getAsInt();
|
||||
if (message.trim().length() == 0) {
|
||||
IOHelper.SendResponse(400, "<h1>400 Bad request</h1><p>The message cannot be empty.</p>", exchange);
|
||||
return;
|
||||
}
|
||||
LoaderCollection<Conversation> convos = user.getConversations();
|
||||
Conversation conv = null;
|
||||
LogManager.getLogger().log(Level.DEBUG, "Len: " + convos.size());
|
||||
for (Conversation con : convos) {
|
||||
LogManager.getLogger().log(Level.DEBUG, con.getId());
|
||||
if (con.getId() == conversation) {
|
||||
conv = con;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (conv == null) {
|
||||
IOHelper.SendResponse(400, "<h1>400 Conversation not found</h1><p>The conversation with the id "
|
||||
+ conversation + " is not found.</p>", exchange);
|
||||
return;
|
||||
}
|
||||
MessageChunk chunk = ManagedData.create(MessageChunk.class);
|
||||
chunk.setConversation(conv);
|
||||
Message msg = new Message();
|
||||
msg.setSender(user);
|
||||
msg.setMessage(message);
|
||||
msg.setTime(new Date());
|
||||
msg.setMessageChunk(chunk);
|
||||
chunk.getMessages().add(msg);
|
||||
conv.getMesssageChunks().add(chunk);
|
||||
DataManager.save(conv);
|
||||
LogManager.getLogger().log(Level.DEBUG,
|
||||
"Added conversation's message count: " + conv.getMesssageChunks().size());
|
||||
JsonObject obj = new JsonObject(); // TODO
|
||||
/*
|
||||
* String message = obj.get("message").getAsString().trim(); int conversation = obj.get("conversation").getAsInt(); if (message.trim().length() == 0) { IOHelper.SendResponse(400,
|
||||
* "<h1>400 Bad request</h1><p>The message cannot be empty.</p>", exchange); return; } LoaderCollection<Conversation> convos = user.getConversations(); Conversation conv = null;
|
||||
* LogManager.getLogger().log(Level.DEBUG, "Len: " + convos.size()); for (Conversation con : convos) { LogManager.getLogger().log(Level.DEBUG, con.getId()); if (con.getId() == conversation) {
|
||||
* conv = con; break; } } if (conv == null) { IOHelper.SendResponse(400, "<h1>400 Conversation not found</h1><p>The conversation with the id " + conversation + " is not found.</p>", exchange);
|
||||
* return; } MessageChunk chunk = ManagedData.create(MessageChunk.class); chunk.setConversation(conv); Message msg = new Message(); msg.setSender(user); msg.setMessage(message);
|
||||
* msg.setTime(new Date()); msg.setMessageChunk(chunk); chunk.getMessages().add(msg); conv.getMesssageChunks().add(chunk); DataManager.save(conv); LogManager.getLogger().log(Level.DEBUG,
|
||||
* "Added conversation's message count: " + conv.getMesssageChunks().size());
|
||||
*/
|
||||
|
||||
IOHelper.SendResponse(200, "Success", exchange);
|
||||
}
|
||||
|
|
|
@ -64,16 +64,11 @@ public class SendMessageAjaxPage extends Page {
|
|||
+ conversation + " is not found.</p>", exchange);
|
||||
return;
|
||||
}
|
||||
MessageChunk chunk = ManagedData.create(MessageChunk.class); // TODO: Automatize
|
||||
chunk.setConversation(conv);
|
||||
Message msg = new Message();
|
||||
Message msg = ManagedData.create(Message.class);
|
||||
msg.setConversation(conv);
|
||||
msg.setSender(user);
|
||||
LogManager.getLogger().debug(message);
|
||||
msg.setMessage(message);
|
||||
msg.setTime(new Date());
|
||||
msg.setMessageChunk(chunk); // TODO: Store relations at one side or both
|
||||
chunk.getMessages().add(msg);
|
||||
conv.getMesssageChunks().add(chunk);
|
||||
DataManager.save(conv);
|
||||
LogManager.getLogger().log(Level.DEBUG,
|
||||
"Added conversation's message count: " + conv.getMesssageChunks().size());
|
||||
|
|
Loading…
Reference in a new issue