From e7a711bde53b0ff5410145fe4574e02011eaeb5b Mon Sep 17 00:00:00 2001
From: NorbiPeti
Date: Tue, 2 Aug 2016 15:03:11 +0200
Subject: [PATCH] Switched to JSON, created lazily loaded collection
---
.gitignore | 2 +
main/resources/META-INF/persistence.xml | 2 +-
pom.xml | 14 +-
.../norbipeti/chat/server/IOHelper.java | 35 +--
src/io/github/norbipeti/chat/server/Main.java | 107 +++++----
.../chat/server/data/DataManager.java | 61 +++++
.../chat/server/data/LoaderCollection.java | 208 ++++++++++++++++++
.../chat/server/data/LoaderIterator.java | 35 +++
.../chat/server/data/LoaderListIterator.java | 64 ++++++
.../chat/server/db/DataProvider.java | 3 +-
.../server/db/domain/ChatDatabaseEntity.java | 10 +
.../chat/server/db/domain/Conversation.java | 15 +-
.../chat/server/db/domain/Message.java | 13 +-
.../norbipeti/chat/server/db/domain/User.java | 55 +++--
.../norbipeti/chat/server/page/IndexPage.java | 24 +-
.../chat/server/page/LoginAjaxPage.java | 38 ++--
.../chat/server/page/MessageAjaxPage.java | 37 ++--
.../chat/server/page/RegisterAjaxPage.java | 52 ++---
18 files changed, 567 insertions(+), 208 deletions(-)
create mode 100644 src/io/github/norbipeti/chat/server/data/DataManager.java
create mode 100644 src/io/github/norbipeti/chat/server/data/LoaderCollection.java
create mode 100644 src/io/github/norbipeti/chat/server/data/LoaderIterator.java
create mode 100644 src/io/github/norbipeti/chat/server/data/LoaderListIterator.java
diff --git a/.gitignore b/.gitignore
index c96d30a..db08139 100644
--- a/.gitignore
+++ b/.gitignore
@@ -249,3 +249,5 @@ paket-files/
target/classes/*
/target/
+
+chatdb/
diff --git a/main/resources/META-INF/persistence.xml b/main/resources/META-INF/persistence.xml
index 49b3b59..2a5549b 100644
--- a/main/resources/META-INF/persistence.xml
+++ b/main/resources/META-INF/persistence.xml
@@ -5,7 +5,7 @@
-
+
diff --git a/pom.xml b/pom.xml
index 3a008df..1a95534 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,11 +64,8 @@
2.6.2
-
- org.json
- json
- 20160212
-
+
org.hibernate
@@ -86,7 +83,6 @@
spring-tx
${spring-framework.version}
-
org.springframework
@@ -98,6 +94,12 @@
spring-jdbc
${spring-framework.version}
+
+
+ com.google.code.gson
+ gson
+ 2.7
+
1.8
diff --git a/src/io/github/norbipeti/chat/server/IOHelper.java b/src/io/github/norbipeti/chat/server/IOHelper.java
index 7a47da7..3a6a7b0 100644
--- a/src/io/github/norbipeti/chat/server/IOHelper.java
+++ b/src/io/github/norbipeti/chat/server/IOHelper.java
@@ -18,13 +18,14 @@ import java.util.function.Function;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
-import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
import com.sun.net.httpserver.HttpExchange;
-import io.github.norbipeti.chat.server.db.DataProvider;
+import io.github.norbipeti.chat.server.data.DataManager;
import io.github.norbipeti.chat.server.db.domain.User;
import io.github.norbipeti.chat.server.page.Page;
@@ -66,7 +67,6 @@ public class IOHelper {
return content;
}
- @Deprecated
public static HashMap GetPOST(HttpExchange exchange) throws IOException {
if (exchange.getRequestBody().available() == 0)
return new HashMap<>();
@@ -87,12 +87,12 @@ public class IOHelper {
}
}
- public static JSONObject GetPOSTJSON(HttpExchange exchange) throws IOException {
+ public static JsonObject GetPOSTJSON(HttpExchange exchange) throws IOException {
if (exchange.getRequestBody().available() == 0)
return null;
try {
String content = IOUtils.toString(exchange.getRequestBody(), StandardCharsets.ISO_8859_1).trim();
- JSONObject obj = new JSONObject(content);
+ JsonObject obj = new JsonParser().parse(content).getAsJsonObject();
return obj;
} catch (Exception e) {
e.printStackTrace();
@@ -111,12 +111,17 @@ public class IOHelper {
return true;
}
- public static void LoginUser(HttpExchange exchange, User user, DataProvider provider) {
+ /**
+ * Sends login headers and sets the session id on the user
+ *
+ * @param exchange
+ * @param user
+ */
+ public static void LoginUser(HttpExchange exchange, User user) {
LogManager.getLogger().log(Level.DEBUG, "Logging in user: " + user);
// provider.SetValues(() ->
// user.setSessionid(UUID.randomUUID().toString()));
user.setSessionid(UUID.randomUUID().toString());
- user = provider.save(user);
ZonedDateTime expiretime = ZonedDateTime.now(ZoneId.of("GMT")).plus(Period.of(2, 0, 0));
exchange.getResponseHeaders().add("Set-Cookie",
"user_id=" + user.getId() + "; expires=" + expiretime.format(DateTimeFormatter.RFC_1123_DATE_TIME));
@@ -162,19 +167,17 @@ public class IOHelper {
*
* @param exchange
* @return The logged in user or null if not logged in.
+ * @throws IOException
*/
- public static User GetLoggedInUser(HttpExchange exchange) {
+ public static User GetLoggedInUser(HttpExchange exchange) throws IOException {
HashMap cookies = GetCookies(exchange);
if (!cookies.containsKey("user_id") || !cookies.containsKey("session_id"))
return null;
- try (DataProvider provider = new DataProvider()) {
- User user = provider.getUser(Long.parseLong(cookies.get("user_id")));
- if (user != null && cookies.get("session_id") != null
- && cookies.get("session_id").equals(user.getSessionid()))
- return user;
- else
- SendLogoutHeaders(exchange);
- }
+ User user = DataManager.load(User.class, Long.parseLong(cookies.get("user_id")));
+ if (user != null && cookies.get("session_id") != null && cookies.get("session_id").equals(user.getSessionid()))
+ return user;
+ else
+ SendLogoutHeaders(exchange);
return null;
}
diff --git a/src/io/github/norbipeti/chat/server/Main.java b/src/io/github/norbipeti/chat/server/Main.java
index 68ad7c2..9809467 100644
--- a/src/io/github/norbipeti/chat/server/Main.java
+++ b/src/io/github/norbipeti/chat/server/Main.java
@@ -4,23 +4,17 @@ import java.lang.reflect.Modifier;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Date;
-import java.util.List;
import java.util.Set;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.core.config.LoggerConfig;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.jdbc.core.JdbcTemplate;
-
import com.sun.net.httpserver.HttpServer;
-import io.github.norbipeti.chat.server.db.*;
+
+import io.github.norbipeti.chat.server.data.DataManager;
import io.github.norbipeti.chat.server.db.domain.*;
import io.github.norbipeti.chat.server.page.*;
@@ -30,52 +24,53 @@ public class Main {
// https://docs.oracle.com/javase/8/docs/jre/api/net/httpserver/spec/
// https://docs.oracle.com/javase/8/docs/api/
LogManager.getLogger().log(Level.INFO, "Loading database...");
- try (DataProvider provider = new DataProvider()) {
- User user = new User();
- user.setName("asd");
- user.setEmail("test@test.com");
- User user2 = new User();
- user2.setName("Teszt");
- user2.setEmail("test2@test.com");
- // user = provider.save(user);
- // user2 = provider.save(user2);
- user.getContacts().add(user2);
- user2.getContacts().add(user);
- LogManager.getLogger().log(Level.DEBUG, "1st's contact: " + user.getContacts().get(0));
- LogManager.getLogger().log(Level.DEBUG, "2nd's contact: " + user2.getContacts().get(0));
- Conversation conversation = new Conversation();
- conversation = provider.save(conversation);
- conversation.getUsers().add(user);
- user.getConversations().add(conversation);
- LogManager.getLogger().debug("User: " + user);
- conversation.getUsers().add(user2);
- LogManager.getLogger().debug("User2: " + user2); // TODO: Switch
- // to JSON
- // files?
- user2.getConversations().add(conversation); // TODO: Fix
- // duplicate
- // key constraint
- Message msg = new Message();
- msg.setSender(user);
- msg.setTime(new Date());
- msg.setMessage("Teszt 1");
- conversation.getMesssages().add(msg);
- Message msg2 = new Message();
- msg2.setSender(user2);
- msg2.setTime(new Date());
- msg2.setMessage("Teszt 2");
- conversation.getMesssages().add(msg2);
- // provider.save(user);
- // provider.save(user2);
- /*
- * User loggedinuser = new User(); provider.save(loggedinuser);
- * loggedinuser.setName("NorbiPeti"); loggedinuser.setSessionid(
- * "093b1395-8c31-4f3b-ba67-828a755af92e");
- * loggedinuser.setEmail("sznp@asd.com");
- * conversation.getUsers().add(loggedinuser);
- * loggedinuser.getConversations().add(conversation);
- */
- }
+ User user = new User();
+ user.setName("asd");
+ user.setEmail("test@test.com");
+ User user2 = new User();
+ user2.setName("Teszt");
+ user2.setEmail("test2@test.com");
+ // user = provider.save(user);
+ // user2 = provider.save(user2);
+ user.getContacts().add(user2);
+ user2.getContacts().add(user);
+ LogManager.getLogger().log(Level.DEBUG, "1st's contact: " + user.getContacts().get(0));
+ LogManager.getLogger().log(Level.DEBUG, "2nd's contact: " + user2.getContacts().get(0));
+ Conversation conversation = new Conversation();
+ conversation.getUsers().add(user);
+ user.getConversations().add(conversation);
+ LogManager.getLogger().debug("User: " + user);
+ // conversation.getUsers().add(user2); - TODO
+ LogManager.getLogger().debug("User2: " + user2); // TODO: Switch
+ // to JSON
+ // files?
+ // user2.getConversations().add(conversation); // TODO: Fix
+ // duplicate
+ // key constraint
+ Message msg = new Message();
+ msg.setSender(user);
+ msg.setTime(new Date());
+ msg.setMessage("Teszt 1");
+ conversation.getMesssages().add(msg);
+ Message msg2 = new Message();
+ msg2.setSender(user2);
+ msg2.setTime(new Date());
+ msg2.setMessage("Teszt 2");
+ conversation.getMesssages().add(msg2);
+ // provider.save(user);
+ // provider.save(user2);s
+ User loggedinuser = new User();
+ loggedinuser.setName("NorbiPeti");
+ loggedinuser.setSessionid("093b1395-8c31-4f3b-ba67-828a755af92e");
+ loggedinuser.setEmail("sznp@asd.com");
+ loggedinuser.getContacts().add(user2);
+ conversation.getUsers().add(loggedinuser);
+ loggedinuser.getConversations().add(conversation);
+ DataManager.save(user);
+ DataManager.save(user2);
+ DataManager.save(loggedinuser);
+ DataManager.save(conversation);
+
LogManager.getLogger().log(Level.INFO, "Starting webserver...");
HttpServer server = HttpServer.create(new InetSocketAddress(InetAddress.getLocalHost(), 8080), 10);
Reflections rf = new Reflections(
@@ -100,7 +95,9 @@ public class Main {
System.in.read();
LogManager.getLogger().log(Level.INFO, "Stopping...");
server.stop(1);
- } catch (Exception e) {
+ } catch (
+
+ Exception e) {
e.printStackTrace();
}
LogManager.getLogger().log(Level.INFO, "Stopped");
diff --git a/src/io/github/norbipeti/chat/server/data/DataManager.java b/src/io/github/norbipeti/chat/server/data/DataManager.java
new file mode 100644
index 0000000..d8bc395
--- /dev/null
+++ b/src/io/github/norbipeti/chat/server/data/DataManager.java
@@ -0,0 +1,61 @@
+package io.github.norbipeti.chat.server.data;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import com.google.common.io.Files;
+import com.google.gson.Gson;
+import io.github.norbipeti.chat.server.db.domain.ChatDatabaseEntity;
+
+public final class DataManager {
+ private DataManager() {
+ }
+
+ public static void save(T object) throws IOException {
+ Gson gson = new Gson();
+ Files.write(gson.toJson(object), new File(object.getClass().getName() + "-" + object.getId()),
+ StandardCharsets.UTF_8);
+ }
+
+ public static T load(Class cl, long id) {
+ return loadFromFile(new File(cl.getName() + "-" + id), cl);
+ }
+
+ public static LoaderCollection load(Class cl) {
+ String[] filenames = new File(".").list(new FilenameFilter() {
+
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.startsWith(cl.getName() + "-");
+ }
+ });
+ LoaderCollection rets = new LoaderCollection(cl, filenames.length);
+ for (int i = 0; i < filenames.length; i++) {
+ rets.add(loadFromFile(new File(filenames[i]), cl));
+ }
+ return rets;
+ }
+
+ private static T loadFromFile(File file, Class cl) {
+ try {
+ if (!file.exists())
+ return cl.newInstance();
+ BufferedReader reader = Files.newReader(file, StandardCharsets.UTF_8);
+ String objstr = "";
+ String line;
+ while ((line = reader.readLine()) != null)
+ objstr += line;
+ Gson gson = new Gson();
+ return gson.fromJson(objstr, cl);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static boolean remove(T obj) {
+ return new File(obj.getClass().getName() + "-" + obj.getId()).delete();
+ }
+}
diff --git a/src/io/github/norbipeti/chat/server/data/LoaderCollection.java b/src/io/github/norbipeti/chat/server/data/LoaderCollection.java
new file mode 100644
index 0000000..1b251fe
--- /dev/null
+++ b/src/io/github/norbipeti/chat/server/data/LoaderCollection.java
@@ -0,0 +1,208 @@
+package io.github.norbipeti.chat.server.data;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.stream.Collectors;
+
+import io.github.norbipeti.chat.server.db.domain.ChatDatabaseEntity;
+
+public class LoaderCollection implements List, Serializable {
+ private static final long serialVersionUID = 5426152406394894301L;
+ private List contacts;
+ private Class cl;
+
+ /**
+ * Only used for serialization
+ */
+ @Deprecated
+ public LoaderCollection() {
+ }
+
+ public LoaderCollection(Class cl) {
+ this.cl = cl;
+ contacts = new ArrayList<>();
+ }
+
+ public LoaderCollection(LoaderCollection parentofsub, int fromIndex, int toIndex) {
+ this.cl = parentofsub.cl;
+ contacts = parentofsub.contacts.subList(fromIndex, toIndex);
+ }
+
+ public LoaderCollection(Class cl, int capacity) {
+ this.cl = cl;
+ contacts = new ArrayList<>(capacity);
+ }
+
+ @Override
+ public Iterator iterator() {
+ return new LoaderIterator(contacts.iterator(), cl);
+ }
+
+ @Override
+ public boolean add(T e) {
+ return contacts.add(e.getId());
+ }
+
+ @Override
+ public void add(int index, T element) {
+ contacts.add(index, element.getId());
+ }
+
+ @Override
+ public boolean addAll(Collection extends T> c) {
+ return contacts
+ .addAll(c.stream().map((data) -> ((ChatDatabaseEntity) data).getId()).collect(Collectors.toList()));
+ }
+
+ @Override
+ public boolean addAll(int index, Collection extends T> c) {
+ return contacts.addAll(index,
+ c.stream().map((data) -> ((ChatDatabaseEntity) data).getId()).collect(Collectors.toList()));
+ }
+
+ @Override
+ public void clear() {
+ contacts.clear();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return contacts.contains(o);
+ }
+
+ @Override
+ public boolean containsAll(Collection> c) {
+ return contacts.containsAll(c);
+ }
+
+ @Override
+ public T get(int index) {
+ return DataManager.load(cl, contacts.get(index));
+ }
+
+ @Override
+ public int indexOf(Object o) {
+ return contacts.indexOf(o);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return contacts.isEmpty();
+ }
+
+ @Override
+ public int lastIndexOf(Object o) {
+ return contacts.lastIndexOf(o);
+ }
+
+ @Override
+ public ListIterator listIterator() {
+ return new LoaderListIterator(contacts.listIterator(), cl);
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ return new LoaderListIterator(contacts.listIterator(index), cl);
+ }
+
+ /**
+ * Remove an object from this collection
+ *
+ * @param o
+ * Either the object of type T or the ID
+ */
+ @Override
+ public boolean remove(Object o) {
+ if (ChatDatabaseEntity.class.isAssignableFrom(o.getClass()))
+ return contacts.remove(((ChatDatabaseEntity) o).getId());
+ return contacts.remove(o);
+ }
+
+ @Override
+ public T remove(int index) {
+ return DataManager.load(cl, contacts.remove(index));
+ }
+
+ @Override
+ public boolean removeAll(Collection> c) {
+ boolean success = false;
+ for (Object item : c) {
+ if (ChatDatabaseEntity.class.isAssignableFrom(item.getClass())) {
+ if (contacts.remove(((ChatDatabaseEntity) item).getId())) {
+ success = true;
+ break;
+ }
+ } else {
+ if (contacts.remove(item)) {
+ success = true;
+ break;
+ }
+ }
+ }
+ return success;
+ }
+
+ @Override
+ public boolean retainAll(Collection> c) {
+ List list = new ArrayList();
+ for (Object item : c) {
+ if (ChatDatabaseEntity.class.isAssignableFrom(item.getClass())) {
+ list.add(((ChatDatabaseEntity) item).getId());
+ } else if (Long.class.isAssignableFrom(item.getClass())) {
+ list.add((Long) item);
+ }
+ }
+ return contacts.retainAll(list);
+ }
+
+ @Override
+ public T set(int index, T element) {
+ return DataManager.load(cl, contacts.set(index, element.getId()));
+ }
+
+ @Override
+ public int size() {
+ return contacts.size();
+ }
+
+ @Override
+ public List subList(int fromIndex, int toIndex) {
+ // TODO Auto-generated method stub
+ return new LoaderCollection(this, fromIndex, toIndex);
+ }
+
+ @Override
+ public Object[] toArray() {
+ return contacts.stream().map((data) -> {
+ return DataManager.load(cl, data);
+ }).collect(Collectors.toList()).toArray();
+ }
+
+ @Override
+ public U[] toArray(U[] a) {
+ return contacts.stream().map((data) -> {
+ return DataManager.load(cl, data);
+ }).collect(Collectors.toList()).toArray(a);
+ }
+
+ @Override
+ public String toString() {
+ return toString(false);
+ }
+
+ public String toString(boolean loaditems) {
+ StringBuilder sb = new StringBuilder("[");
+ for (Long item : contacts) {
+ if (loaditems)
+ sb.append(DataManager.load(cl, item));
+ else
+ sb.append(item);
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+}
diff --git a/src/io/github/norbipeti/chat/server/data/LoaderIterator.java b/src/io/github/norbipeti/chat/server/data/LoaderIterator.java
new file mode 100644
index 0000000..bf73a2b
--- /dev/null
+++ b/src/io/github/norbipeti/chat/server/data/LoaderIterator.java
@@ -0,0 +1,35 @@
+package io.github.norbipeti.chat.server.data;
+
+import java.util.Iterator;
+import java.util.ListIterator;
+
+import io.github.norbipeti.chat.server.db.domain.ChatDatabaseEntity;
+
+public final class LoaderIterator implements Iterator {
+ private Iterator iterator;
+ private T lastitem;
+ private Class cl;
+
+ LoaderIterator(Iterator listiterator, Class cl) {
+ this.iterator = listiterator;
+ this.cl = cl;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @Override
+ public T next() {
+ return lastitem = DataManager.load(cl, iterator.next());
+ }
+
+ @Override
+ public void remove() {
+ if (lastitem == null)
+ throw new IllegalStateException();
+ DataManager.remove(lastitem);
+ lastitem = null;
+ }
+}
diff --git a/src/io/github/norbipeti/chat/server/data/LoaderListIterator.java b/src/io/github/norbipeti/chat/server/data/LoaderListIterator.java
new file mode 100644
index 0000000..2d87537
--- /dev/null
+++ b/src/io/github/norbipeti/chat/server/data/LoaderListIterator.java
@@ -0,0 +1,64 @@
+package io.github.norbipeti.chat.server.data;
+
+import java.util.ListIterator;
+
+import io.github.norbipeti.chat.server.db.domain.ChatDatabaseEntity;
+
+public final class LoaderListIterator implements ListIterator {
+ private ListIterator listiterator;
+ private T lastitem;
+ private Class cl;
+
+ LoaderListIterator(ListIterator listiterator, Class cl) {
+ this.listiterator = listiterator;
+ this.cl = cl;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return listiterator.hasNext();
+ }
+
+ @Override
+ public T next() {
+ return lastitem = DataManager.load(cl, listiterator.next());
+ }
+
+ @Override
+ public void remove() {
+ if (lastitem == null)
+ throw new IllegalStateException();
+ DataManager.remove(lastitem);
+ lastitem = null;
+ }
+
+ @Override
+ public void add(T e) {
+ listiterator.add(e.getId());
+ }
+
+ @Override
+ public boolean hasPrevious() {
+ return listiterator.hasPrevious();
+ }
+
+ @Override
+ public int nextIndex() {
+ return listiterator.nextIndex();
+ }
+
+ @Override
+ public T previous() {
+ return DataManager.load(cl, listiterator.previous());
+ }
+
+ @Override
+ public int previousIndex() {
+ return listiterator.previousIndex();
+ }
+
+ @Override
+ public void set(T e) {
+ listiterator.set(e.getId());
+ }
+}
diff --git a/src/io/github/norbipeti/chat/server/db/DataProvider.java b/src/io/github/norbipeti/chat/server/db/DataProvider.java
index de8ee85..74d7099 100644
--- a/src/io/github/norbipeti/chat/server/db/DataProvider.java
+++ b/src/io/github/norbipeti/chat/server/db/DataProvider.java
@@ -7,10 +7,9 @@ import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import org.hibernate.Hibernate;
-import org.hibernate.Session;
-
import io.github.norbipeti.chat.server.db.domain.*;
+@Deprecated
public class DataProvider implements AutoCloseable {
private EntityManagerFactory emf;
private EntityManager em;
diff --git a/src/io/github/norbipeti/chat/server/db/domain/ChatDatabaseEntity.java b/src/io/github/norbipeti/chat/server/db/domain/ChatDatabaseEntity.java
index 21f0085..2125011 100644
--- a/src/io/github/norbipeti/chat/server/db/domain/ChatDatabaseEntity.java
+++ b/src/io/github/norbipeti/chat/server/db/domain/ChatDatabaseEntity.java
@@ -4,5 +4,15 @@ import java.io.Serializable;
@SuppressWarnings("serial")
public abstract class ChatDatabaseEntity implements Serializable {
+ private static long nextID = 0;
+ private long id;
+
+ public long getId() {
+ return id;
+ }
+
+ protected ChatDatabaseEntity() {
+ id = nextID++;
+ }
}
diff --git a/src/io/github/norbipeti/chat/server/db/domain/Conversation.java b/src/io/github/norbipeti/chat/server/db/domain/Conversation.java
index 1129ccc..6059f1c 100644
--- a/src/io/github/norbipeti/chat/server/db/domain/Conversation.java
+++ b/src/io/github/norbipeti/chat/server/db/domain/Conversation.java
@@ -8,12 +8,13 @@ import java.util.Set;
import javax.persistence.*;
@Entity
+@Table(name = "CONVERSATION")
public class Conversation extends ChatDatabaseEntity {
private static final long serialVersionUID = 5058682475353799722L;
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- @Column(name = "id", unique = true, nullable = false)
- private Long id;
+ //@Id
+ //@GeneratedValue(strategy = GenerationType.IDENTITY)
+ //@Column(name = "ID", unique = true, nullable = false)
+ //private Long id;
@ElementCollection(fetch = FetchType.EAGER)
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "conversation")
private List messsages;
@@ -27,7 +28,7 @@ public class Conversation extends ChatDatabaseEntity {
// @JoinTable(name = "User_Conversation", joinColumns = @JoinColumn(name =
// "conversation_id", referencedColumnName = "id"), inverseJoinColumns =
// @JoinColumn(name = "user_id", referencedColumnName = "id"))
- @JoinTable(name = "User_Conversation")
+ // @JoinTable(name = "User_Conversation")
private Set users;
public List getMesssages() {
@@ -50,11 +51,11 @@ public class Conversation extends ChatDatabaseEntity {
this.users = users;
}
- public Long getId() {
+ /*public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
- }
+ }*/
}
diff --git a/src/io/github/norbipeti/chat/server/db/domain/Message.java b/src/io/github/norbipeti/chat/server/db/domain/Message.java
index 9d23dde..3b0762b 100644
--- a/src/io/github/norbipeti/chat/server/db/domain/Message.java
+++ b/src/io/github/norbipeti/chat/server/db/domain/Message.java
@@ -5,12 +5,13 @@ import java.util.Date;
import javax.persistence.*;
@Entity
+@Table(name = "MESSAGE")
public class Message extends ChatDatabaseEntity {
private static final long serialVersionUID = 6345941601716826570L;
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- @Column(name = "id", unique = true, nullable = false)
- private Long id;
+ //@Id
+ //@GeneratedValue(strategy = GenerationType.IDENTITY)
+ //@Column(name = "ID", unique = true, nullable = false)
+ //private Long id;
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
// @JoinTable(name="user_message")
private User sender;
@@ -52,11 +53,11 @@ public class Message extends ChatDatabaseEntity {
this.conversation = conversation;
}
- public Long getId() {
+ /*public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
- }
+ }*/
}
diff --git a/src/io/github/norbipeti/chat/server/db/domain/User.java b/src/io/github/norbipeti/chat/server/db/domain/User.java
index 292cc69..25a9f55 100644
--- a/src/io/github/norbipeti/chat/server/db/domain/User.java
+++ b/src/io/github/norbipeti/chat/server/db/domain/User.java
@@ -1,5 +1,6 @@
package io.github.norbipeti.chat.server.db.domain;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -7,27 +8,30 @@ import java.util.Set;
import javax.persistence.*;
+import io.github.norbipeti.chat.server.data.DataManager;
+import io.github.norbipeti.chat.server.data.LoaderCollection;
+
@Entity
-@Table(name = "\"User\"")
+@Table(name = "\"USER\"")
public class User extends ChatDatabaseEntity {
private static final long serialVersionUID = 2862762084164225666L;
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- @Column(name = "id", unique = true, nullable = false)
- private Long id;
+ // @Id
+ // @GeneratedValue(strategy = GenerationType.IDENTITY)
+ // @Column(name = "ID", unique = true, nullable = false)
+ // private Long id;
private String name;
private String email;
private String password;
@ElementCollection(fetch = FetchType.EAGER)
- @ManyToMany(cascade = CascadeType.ALL)
- private List contacts;
+ @OneToOne(cascade = CascadeType.ALL)
+ private LoaderCollection contacts;
private String salt;
// @Column(columnDefinition = "CHAR(16) FOR BIT DATA")
@Column(columnDefinition = "VARCHAR(64)")
private String sessionid;
@ElementCollection(fetch = FetchType.EAGER)
// @ManyToMany(fetch = FetchType.EAGER, mappedBy = "users")
- @ManyToMany(mappedBy = "users", fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
+ @ManyToMany(mappedBy = "USER", fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
// @ManyToMany(mappedBy = "users")
// @JoinTable(name = "User_Conversation", joinColumns =
// @JoinColumn(referencedColumnName = "id", unique = false),
@@ -35,16 +39,18 @@ public class User extends ChatDatabaseEntity {
// false))
private Set conversations;
- public List getContacts() {
+ /**
+ * Loads all contact data
+ *
+ * @return
+ * @throws IOException
+ */
+ public List getContacts() throws IOException {
if (contacts == null)
- contacts = new ArrayList<>();
+ contacts = new LoaderCollection(User.class);
return contacts;
}
- public void setContacts(List contacts) {
- this.contacts = contacts;
- }
-
public String getName() {
return name;
}
@@ -59,14 +65,8 @@ public class User extends ChatDatabaseEntity {
@Override
public String toString() {
- List c = null;
- if (contacts != null) {
- c = new ArrayList<>();
- for (User u : contacts)
- c.add(u.name);
- }
- return "User [id=" + id + ", name=" + name + ", email=" + email + ", password=" + password + ", contacts=" + c
- + ", sessionid=" + sessionid + "]";
+ return "User [id=" + getId() + ", name=" + name + ", email=" + email + ", password=" + password + ", contacts="
+ + contacts + ", sessionid=" + sessionid + "]";
}
public void setEmail(String email) {
@@ -81,14 +81,6 @@ public class User extends ChatDatabaseEntity {
this.password = password;
}
- public Long getId() {
- return id;
- }
-
- public void setId(Long id) {
- this.id = id;
- }
-
public String getSalt() {
return salt;
}
@@ -116,6 +108,9 @@ public class User extends ChatDatabaseEntity {
}
public User() {
+ }
+ public static LoaderCollection getUsers() {
+ return DataManager.load(User.class);
}
}
diff --git a/src/io/github/norbipeti/chat/server/page/IndexPage.java b/src/io/github/norbipeti/chat/server/page/IndexPage.java
index 897d32c..8fa2118 100644
--- a/src/io/github/norbipeti/chat/server/page/IndexPage.java
+++ b/src/io/github/norbipeti/chat/server/page/IndexPage.java
@@ -8,7 +8,7 @@ import org.jsoup.nodes.Element;
import com.sun.net.httpserver.HttpExchange;
import io.github.norbipeti.chat.server.IOHelper;
-import io.github.norbipeti.chat.server.db.DataProvider;
+import io.github.norbipeti.chat.server.data.DataManager;
import io.github.norbipeti.chat.server.db.domain.Conversation;
import io.github.norbipeti.chat.server.db.domain.Message;
import io.github.norbipeti.chat.server.db.domain.User;
@@ -35,18 +35,16 @@ public class IndexPage extends Page {
Element userbox = doc.getElementById("userbox");
userbox.html(userbox.html().replace("", user.getName()));
Element channelmessages = doc.getElementById("channelmessages");
- try (DataProvider provider = new DataProvider()) {
- LogManager.getLogger().log(Level.INFO, "Conversations: " + provider.getConversations().size());
- LogManager.getLogger().log(Level.INFO, "User conversations: " + user.getConversations().size());
- Conversation convo = user.getConversations().iterator().next();
- LogManager.getLogger().log(Level.INFO, "Messages: " + convo.getMesssages().size());
- for (Message message : convo.getMesssages()) {
- Element msgelement = channelmessages.appendElement("div");
- Element header = msgelement.appendElement("p");
- header.text(message.getSender().getName() + " - " + message.getTime());
- Element body = msgelement.appendElement("p");
- body.text(message.getMessage());
- }
+ LogManager.getLogger().log(Level.INFO, "Conversations: " + DataManager.load(Conversation.class).size());
+ LogManager.getLogger().log(Level.INFO, "User conversations: " + user.getConversations().size());
+ Conversation convo = user.getConversations().iterator().next();
+ LogManager.getLogger().log(Level.INFO, "Messages: " + convo.getMesssages().size());
+ for (Message message : convo.getMesssages()) {
+ Element msgelement = channelmessages.appendElement("div");
+ Element header = msgelement.appendElement("p");
+ header.text(message.getSender().getName() + " - " + message.getTime());
+ Element body = msgelement.appendElement("p");
+ body.text(message.getMessage());
}
return doc;
}, exchange);
diff --git a/src/io/github/norbipeti/chat/server/page/LoginAjaxPage.java b/src/io/github/norbipeti/chat/server/page/LoginAjaxPage.java
index c1ff975..1762761 100644
--- a/src/io/github/norbipeti/chat/server/page/LoginAjaxPage.java
+++ b/src/io/github/norbipeti/chat/server/page/LoginAjaxPage.java
@@ -1,44 +1,40 @@
package io.github.norbipeti.chat.server.page;
import java.io.IOException;
-import org.json.JSONObject;
import org.mindrot.jbcrypt.BCrypt;
+import com.google.gson.JsonObject;
import com.sun.net.httpserver.HttpExchange;
import io.github.norbipeti.chat.server.IOHelper;
-import io.github.norbipeti.chat.server.db.DataProvider;
+import io.github.norbipeti.chat.server.data.DataManager;
import io.github.norbipeti.chat.server.db.domain.User;
public class LoginAjaxPage extends Page {
@Override
public void handlePage(HttpExchange exchange) throws IOException {
- JSONObject post = IOHelper.GetPOSTJSON(exchange);
+ JsonObject post = IOHelper.GetPOSTJSON(exchange);
if (post == null || !post.has("email") || !post.has("pass")) {
IOHelper.Redirect("/", exchange);
return;
}
- try (DataProvider provider = new DataProvider()) {
- User loginuser = null;
- for (User user : provider.getUsers()) {
- if (user.getEmail().equals(post.get("email"))) {
- loginuser = user;
- break;
- }
+ User loginuser = null;
+ for (User user : DataManager.load(User.class)) {
+ if (user.getEmail().equals(post.get("email"))) {
+ loginuser = user;
+ break;
}
- if (loginuser == null || !BCrypt.checkpw(post.getString("pass"), loginuser.getPassword())) {
- IOHelper.SendResponse(200, (doc) -> {
- doc.appendElement("p").text("The username or password is invalid.");
- return doc;
- }, exchange);
- return;
- }
- IOHelper.LoginUser(exchange, loginuser, provider);
- IOHelper.SendResponse(200, "Success", exchange);
- } catch (Exception e) {
- throw e;
}
+ if (loginuser == null || !BCrypt.checkpw(post.get("pass").getAsString(), loginuser.getPassword())) {
+ IOHelper.SendResponse(200, (doc) -> {
+ doc.appendElement("p").text("The username or password is invalid.");
+ return doc;
+ }, exchange);
+ return;
+ }
+ IOHelper.LoginUser(exchange, loginuser);
+ IOHelper.SendResponse(200, "Success", exchange);
}
@Override
diff --git a/src/io/github/norbipeti/chat/server/page/MessageAjaxPage.java b/src/io/github/norbipeti/chat/server/page/MessageAjaxPage.java
index 3aceee8..860a130 100644
--- a/src/io/github/norbipeti/chat/server/page/MessageAjaxPage.java
+++ b/src/io/github/norbipeti/chat/server/page/MessageAjaxPage.java
@@ -2,19 +2,15 @@ package io.github.norbipeti.chat.server.page;
import java.io.IOException;
import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
import java.util.Set;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.json.JSONObject;
-
+import com.google.gson.JsonObject;
import com.sun.net.httpserver.HttpExchange;
import io.github.norbipeti.chat.server.IOHelper;
-import io.github.norbipeti.chat.server.db.DataProvider;
+import io.github.norbipeti.chat.server.data.DataManager;
import io.github.norbipeti.chat.server.db.domain.Conversation;
import io.github.norbipeti.chat.server.db.domain.Message;
import io.github.norbipeti.chat.server.db.domain.User;
@@ -33,7 +29,7 @@ public class MessageAjaxPage extends Page {
IOHelper.SendResponse(403, "Please log in to send messages
", exchange);
return; // TODO: Fix sending messages
}
- JSONObject obj = IOHelper.GetPOSTJSON(exchange);
+ JsonObject obj = IOHelper.GetPOSTJSON(exchange);
if (obj == null) {
IOHelper.SendResponse(400,
"400 Bad request
Not a JSON string!
" + IOHelper.GetPOST(exchange) + "
",
@@ -47,8 +43,8 @@ public class MessageAjaxPage extends Page {
exchange);
return;
}
- String message = obj.getString("message");
- int conversation = obj.getInt("conversation");
+ String message = obj.get("message").getAsString();
+ int conversation = obj.get("conversation").getAsInt();
if (message.trim().length() == 0) {
IOHelper.SendResponse(400, "400 Bad request
The message cannot be empty,
", exchange);
return;
@@ -68,20 +64,15 @@ public class MessageAjaxPage extends Page {
+ conversation + " is not found.
", exchange);
return;
}
- try (DataProvider provider = new DataProvider()) {
- Message msg = new Message();
- msg.setSender(user);
- msg.setMessage(message);
- msg.setTime(new Date());
- msg.setConversation(conv);
- provider.save(msg);
- conv.getMesssages().add(msg);
- provider.save(conv);
- LogManager.getLogger().log(Level.DEBUG,
- "Added conversation's message count: " + conv.getMesssages().size());
- } catch (Exception e) {
- throw e;
- }
+ Message msg = new Message();
+ msg.setSender(user);
+ msg.setMessage(message);
+ msg.setTime(new Date());
+ msg.setConversation(conv); // TODO: Store relations at one side or both
+ DataManager.save(msg);
+ conv.getMesssages().add(msg);
+ DataManager.save(conv);
+ LogManager.getLogger().log(Level.DEBUG, "Added conversation's message count: " + conv.getMesssages().size());
IOHelper.SendResponse(200, "Success", exchange);
}
diff --git a/src/io/github/norbipeti/chat/server/page/RegisterAjaxPage.java b/src/io/github/norbipeti/chat/server/page/RegisterAjaxPage.java
index 71452d0..3152e9f 100644
--- a/src/io/github/norbipeti/chat/server/page/RegisterAjaxPage.java
+++ b/src/io/github/norbipeti/chat/server/page/RegisterAjaxPage.java
@@ -1,19 +1,19 @@
package io.github.norbipeti.chat.server.page;
import java.io.IOException;
-import org.json.JSONObject;
import org.mindrot.jbcrypt.BCrypt;
+import com.google.gson.JsonObject;
import com.sun.net.httpserver.HttpExchange;
import io.github.norbipeti.chat.server.IOHelper;
-import io.github.norbipeti.chat.server.db.DataProvider;
+import io.github.norbipeti.chat.server.data.DataManager;
import io.github.norbipeti.chat.server.db.domain.User;
public class RegisterAjaxPage extends Page {
@Override
public void handlePage(HttpExchange exchange) throws IOException {
- JSONObject post = IOHelper.GetPOSTJSON(exchange);
+ JsonObject post = IOHelper.GetPOSTJSON(exchange);
if (post != null) {
String errormsg = CheckValues(post, "name", "email", "pass", "pass2");
if (errormsg.length() > 0) {
@@ -21,40 +21,36 @@ public class RegisterAjaxPage extends Page {
IOHelper.SendResponse(200, (doc) -> doc.html(msg).ownerDocument(), exchange);
return; // TODO: Use JavaScript too, for error checks
}
- try (DataProvider provider = new DataProvider()) {
- for (User user : provider.getUsers()) {
- if (post.get("email").equals(user.getEmail())) {
- errormsg += "An user with this name already exists
";
- break;
- }
+ for (User user : DataManager.load(User.class)) { // TODO: Optimize
+ if (post.get("email").equals(user.getEmail())) {
+ errormsg += "An user with this name already exists
";
+ break;
}
- if (!post.get("pass").equals(post.get("pass2")))
- errormsg += "The passwords don't match
";
- if (errormsg.length() > 0) {
- final String msg = errormsg;
- IOHelper.SendResponse(200, (doc) -> doc.html(msg).ownerDocument(), exchange);
- return;
- }
- User user = new User();
- user.setName(post.getString("name"));
- user.setEmail(post.getString("email"));
- user.setSalt(BCrypt.gensalt()); // http://www.mindrot.org/projects/jBCrypt/
- user.setPassword(BCrypt.hashpw(post.getString("pass"), user.getSalt()));
- user = provider.save(user);
- IOHelper.LoginUser(exchange, user, provider);
- IOHelper.SendResponse(200, "Success", exchange);
- } catch (Exception e) {
- throw e;
}
+ if (!post.get("pass").equals(post.get("pass2")))
+ errormsg += "The passwords don't match
";
+ if (errormsg.length() > 0) {
+ final String msg = errormsg;
+ IOHelper.SendResponse(200, (doc) -> doc.html(msg).ownerDocument(), exchange);
+ return;
+ }
+ User user = new User();
+ user.setName(post.get("name").getAsString());
+ user.setEmail(post.get("email").getAsString());
+ user.setSalt(BCrypt.gensalt()); // http://www.mindrot.org/projects/jBCrypt/
+ user.setPassword(BCrypt.hashpw(post.get("pass").getAsString(), user.getSalt()));
+ IOHelper.LoginUser(exchange, user);
+ DataManager.save(user);
+ IOHelper.SendResponse(200, "Success", exchange);
return;
}
IOHelper.Redirect("/", exchange);
}
- private String CheckValues(JSONObject post, String... values) {
+ private String CheckValues(JsonObject post, String... values) {
String errormsg = "";
for (String value : values)
- if (!CheckValue(post.getString(value)))
+ if (!CheckValue(post.get(value).getAsString()))
errormsg += "" + value + " can't be empty
";
return errormsg;
}