Message listener in progress with a refactoring still

This commit is contained in:
Norbi Peti 2016-08-11 13:31:11 +02:00
parent b81f1b2a81
commit 319a2a9aa1
12 changed files with 96 additions and 95 deletions

View file

@ -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>

View file

@ -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...");

View file

@ -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

View file

@ -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;
}

View file

@ -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]);

View file

@ -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() {
}
}

View file

@ -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() {
}
}

View file

@ -0,0 +1,6 @@
package io.github.norbipeti.chat.server.db.domain;
@SuppressWarnings("serial")
public abstract class SavedData extends ManagedData {
}

View file

@ -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() {
}
}

View file

@ -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));

View file

@ -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);
}

View file

@ -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());