Switched to JSON, created lazily loaded collection

This commit is contained in:
Norbi Peti 2016-08-02 15:03:11 +02:00
parent 9edb9db0cb
commit e7a711bde5
18 changed files with 567 additions and 208 deletions

2
.gitignore vendored
View file

@ -249,3 +249,5 @@ paket-files/
target/classes/*
/target/
chatdb/

View file

@ -5,7 +5,7 @@
<persistence-unit name="ChatServerPU">
<properties>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:derby:memory:chatserver;create=true" />
<property name="javax.persistence.jdbc.url" value="jdbc:derby:chatdb;create=true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<!-- c3p0 config http://www.hibernate.org/214.html -->

14
pom.xml
View file

@ -64,11 +64,8 @@
<version>2.6.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160212</version>
</dependency>
<!-- <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId>
<version>20160212</version> </dependency> -->
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
<dependency>
<groupId>org.hibernate</groupId>
@ -86,7 +83,6 @@
<artifactId>spring-tx</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- Spring ORM support -->
<dependency>
<groupId>org.springframework</groupId>
@ -98,6 +94,12 @@
<artifactId>spring-jdbc</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.7</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>

View file

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

View file

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

View file

@ -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 <T extends ChatDatabaseEntity> 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 extends ChatDatabaseEntity> T load(Class<T> cl, long id) {
return loadFromFile(new File(cl.getName() + "-" + id), cl);
}
public static <T extends ChatDatabaseEntity> LoaderCollection<T> load(Class<T> cl) {
String[] filenames = new File(".").list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.startsWith(cl.getName() + "-");
}
});
LoaderCollection<T> rets = new LoaderCollection<T>(cl, filenames.length);
for (int i = 0; i < filenames.length; i++) {
rets.add(loadFromFile(new File(filenames[i]), cl));
}
return rets;
}
private static <T extends ChatDatabaseEntity> T loadFromFile(File file, Class<T> 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 <T extends ChatDatabaseEntity> boolean remove(T obj) {
return new File(obj.getClass().getName() + "-" + obj.getId()).delete();
}
}

View file

@ -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<T extends ChatDatabaseEntity> implements List<T>, Serializable {
private static final long serialVersionUID = 5426152406394894301L;
private List<Long> contacts;
private Class<T> cl;
/**
* Only used for serialization
*/
@Deprecated
public LoaderCollection() {
}
public LoaderCollection(Class<T> cl) {
this.cl = cl;
contacts = new ArrayList<>();
}
public LoaderCollection(LoaderCollection<T> parentofsub, int fromIndex, int toIndex) {
this.cl = parentofsub.cl;
contacts = parentofsub.contacts.subList(fromIndex, toIndex);
}
public LoaderCollection(Class<T> cl, int capacity) {
this.cl = cl;
contacts = new ArrayList<>(capacity);
}
@Override
public Iterator<T> iterator() {
return new LoaderIterator<T>(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<T> listIterator() {
return new LoaderListIterator<T>(contacts.listIterator(), cl);
}
@Override
public ListIterator<T> listIterator(int index) {
return new LoaderListIterator<T>(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<Long> list = new ArrayList<Long>();
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<T> subList(int fromIndex, int toIndex) {
// TODO Auto-generated method stub
return new LoaderCollection<T>(this, fromIndex, toIndex);
}
@Override
public Object[] toArray() {
return contacts.stream().map((data) -> {
return DataManager.load(cl, data);
}).collect(Collectors.toList()).toArray();
}
@Override
public <U> 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();
}
}

View file

@ -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<T extends ChatDatabaseEntity> implements Iterator<T> {
private Iterator<Long> iterator;
private T lastitem;
private Class<T> cl;
LoaderIterator(Iterator<Long> listiterator, Class<T> 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;
}
}

View file

@ -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<T extends ChatDatabaseEntity> implements ListIterator<T> {
private ListIterator<Long> listiterator;
private T lastitem;
private Class<T> cl;
LoaderListIterator(ListIterator<Long> listiterator, Class<T> 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());
}
}

View file

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

View file

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

View file

@ -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<Message> 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<User> users;
public List<Message> 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;
}
}*/
}

View file

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

View file

@ -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<User> contacts;
@OneToOne(cascade = CascadeType.ALL)
private LoaderCollection<User> 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<Conversation> conversations;
public List<User> getContacts() {
/**
* Loads all contact data
*
* @return
* @throws IOException
*/
public List<User> getContacts() throws IOException {
if (contacts == null)
contacts = new ArrayList<>();
contacts = new LoaderCollection<User>(User.class);
return contacts;
}
public void setContacts(List<User> contacts) {
this.contacts = contacts;
}
public String getName() {
return name;
}
@ -59,14 +65,8 @@ public class User extends ChatDatabaseEntity {
@Override
public String toString() {
List<String> 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<User> getUsers() {
return DataManager.load(User.class);
}
}

View file

@ -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("<username />", 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);

View file

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

View file

@ -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, "<p>Please log in to send messages</p>", exchange);
return; // TODO: Fix sending messages
}
JSONObject obj = IOHelper.GetPOSTJSON(exchange);
JsonObject obj = IOHelper.GetPOSTJSON(exchange);
if (obj == null) {
IOHelper.SendResponse(400,
"<h1>400 Bad request</h1><p>Not a JSON string!</p><p>" + IOHelper.GetPOST(exchange) + "</p>",
@ -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, "<h1>400 Bad request</h1><p>The message cannot be empty,</p>", exchange);
return;
@ -68,20 +64,15 @@ public class MessageAjaxPage extends Page {
+ conversation + " is not found.</p>", 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);
}

View file

@ -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 += "<p>An user with this name already exists</p>";
break;
}
for (User user : DataManager.load(User.class)) { // TODO: Optimize
if (post.get("email").equals(user.getEmail())) {
errormsg += "<p>An user with this name already exists</p>";
break;
}
if (!post.get("pass").equals(post.get("pass2")))
errormsg += "<p>The passwords don't match</p>";
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 += "<p>The passwords don't match</p>";
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 += "<p>" + value + " can't be empty</p>";
return errormsg;
}