Add client side errors in case of data initialization with null values

This commit is contained in:
Leon Hofmeister 2020-10-22 23:58:55 +02:00
parent 44d3082958
commit 2eeb55ed52
Signed by: delvh
GPG Key ID: 3DECE05F6D9A647C
15 changed files with 72 additions and 41 deletions

View File

@ -1,6 +1,7 @@
package envoy.data;
import java.io.Serializable;
import java.util.Objects;
/**
* This interface should be used for any type supposed to be a {@link Message} attachment (i.e.
@ -63,9 +64,9 @@ public final class Attachment implements Serializable {
* @since Envoy Common v0.1-beta
*/
public Attachment(byte[] data, String name, AttachmentType type) {
this.data = data;
this.name = name;
this.type = type;
this.data = Objects.requireNonNull(data);
this.name = Objects.requireNonNull(name);
this.type = Objects.requireNonNull(type);
}
/**

View File

@ -29,8 +29,8 @@ public abstract class Contact implements Serializable {
*/
public Contact(long id, String name, Set<? extends Contact> contacts) {
this.id = id;
this.name = name;
this.contacts = contacts;
this.name = Objects.requireNonNull(name);
this.contacts = contacts == null ? new HashSet<>() : contacts;
}
/**

View File

@ -38,7 +38,8 @@ public final class GroupMessage extends Message {
Map<Long, MessageStatus> memberStatuses) {
super(id, senderID, groupID, creationDate, receivedDate, readDate, text, attachment, status,
forwarded);
this.memberStatuses = memberStatuses;
this.memberStatuses =
memberStatuses == null ? new HashMap<>() : memberStatuses;
}
/**

View File

@ -2,6 +2,7 @@ package envoy.data;
import java.io.Serializable;
import java.time.Instant;
import java.util.Objects;
/**
* Contains a {@link User}'s login / registration information as well as the client version.
@ -22,12 +23,12 @@ public final class LoginCredentials implements Serializable {
private LoginCredentials(String identifier, String password, boolean registration,
boolean token, String clientVersion,
Instant lastSync) {
this.identifier = identifier;
this.password = password;
this.identifier = Objects.requireNonNull(identifier);
this.password = Objects.requireNonNull(password);
this.registration = registration;
this.token = token;
this.clientVersion = clientVersion;
this.lastSync = lastSync;
this.clientVersion = Objects.requireNonNull(clientVersion);
this.lastSync = lastSync == null ? Instant.EPOCH : lastSync;
}
/**

View File

@ -2,6 +2,7 @@ package envoy.data;
import java.io.Serializable;
import java.time.Instant;
import java.util.Objects;
import dev.kske.eventbus.IEvent;
@ -80,9 +81,9 @@ public class Message implements Serializable, IEvent {
this.creationDate = creationDate;
this.receivedDate = receivedDate;
this.readDate = readDate;
this.text = text;
this.text = text == null ? "" : text;
this.attachment = attachment;
this.status = status;
this.status = Objects.requireNonNull(status);
this.forwarded = forwarded;
}

View File

@ -86,7 +86,7 @@ public final class User extends Contact {
*/
public User(long id, String name, UserStatus status, Set<Contact> contacts) {
super(id, name, contacts);
this.status = status;
this.status = Objects.requireNonNull(status);
}
@Override

View File

@ -1,6 +1,7 @@
package envoy.event;
import java.io.Serializable;
import java.util.Objects;
import dev.kske.eventbus.IEvent;
@ -20,7 +21,16 @@ public abstract class Event<T> implements IEvent, Serializable {
private static final long serialVersionUID = 0L;
protected Event(T value) {
this.value = value;
this(value, false);
}
/**
* This constructor is reserved for {@link Valueless} events. No other event should contain null
* values. Only use if really necessary. Using this constructor with {@code true} implies that
* the user has to manually check if the value of the event is null.
*/
protected Event(T value, boolean canBeNull) {
this.value = canBeNull ? value : Objects.requireNonNull(value);
}
/**
@ -46,7 +56,7 @@ public abstract class Event<T> implements IEvent, Serializable {
private static final long serialVersionUID = 0L;
protected Valueless() {
super(null);
super(null, true);
}
@Override

View File

@ -20,7 +20,7 @@ public class GroupCreationResult extends Event<Group> {
* @since Envoy Common v0.2-beta
*/
public GroupCreationResult() {
super(null);
super(null, true);
}
/**

View File

@ -2,6 +2,8 @@ package envoy.event;
import static envoy.event.ElementOperation.*;
import java.util.Objects;
import envoy.data.*;
/**
@ -30,7 +32,7 @@ public final class GroupResize extends Event<User> {
*/
public GroupResize(User user, Group group, ElementOperation operation) {
super(user);
this.operation = operation;
this.operation = Objects.requireNonNull(operation);
final var contained = group.getContacts().contains(user);
if (contained && operation.equals(ADD))
throw new IllegalArgumentException(String.format("Cannot add %s to %s!", user, group));

View File

@ -28,7 +28,7 @@ public final class IsTyping extends Event<Long> {
* @param destinationID the ID of the contact the user wrote to
* @since Envoy Common v0.2-beta
*/
public IsTyping(Long sourceID, long destinationID) {
public IsTyping(long sourceID, long destinationID) {
super(sourceID);
this.destinationID = destinationID;
}

View File

@ -23,7 +23,7 @@ public final class IssueProposal extends Event<String> {
*/
public IssueProposal(String title, String description, boolean isBug) {
super(escape(title));
this.description = sanitizeDescription(description);
this.description = description == null ? "" : sanitizeDescription(description);
bug = isBug;
}
@ -37,8 +37,8 @@ public final class IssueProposal extends Event<String> {
*/
public IssueProposal(String title, String description, String user, boolean isBug) {
super(escape(title));
this.description =
sanitizeDescription(description) + String.format("<br>Submitted by user %s.", user);
this.description = description == null ? ""
: sanitizeDescription(description) + String.format("<br>Submitted by user %s.", user);
bug = isBug;
}

View File

@ -1,6 +1,7 @@
package envoy.event;
import java.time.Instant;
import java.util.Objects;
import envoy.data.Message;
@ -26,7 +27,7 @@ public class MessageStatusChange extends Event<Message.MessageStatus> {
public MessageStatusChange(long id, Message.MessageStatus status, Instant date) {
super(status);
this.id = id;
this.date = date;
this.date = Objects.requireNonNull(date);
}
/**

View File

@ -1,5 +1,7 @@
package envoy.event;
import java.util.Objects;
import envoy.data.Contact;
/**
@ -21,7 +23,7 @@ public final class PasswordChangeRequest extends Event<String> {
*/
public PasswordChangeRequest(String newPassword, String oldPassword, long userID) {
super(newPassword);
this.oldPassword = oldPassword;
this.oldPassword = Objects.requireNonNull(oldPassword);
id = userID;
}

View File

@ -1,5 +1,7 @@
package envoy.event.contact;
import java.util.Objects;
import envoy.data.User;
import envoy.event.*;
@ -24,7 +26,7 @@ public final class UserOperation extends Event<User> {
*/
public UserOperation(User contact, ElementOperation operationType) {
super(contact);
this.operationType = operationType;
this.operationType = Objects.requireNonNull(operationType);
}
/**

View File

@ -1,7 +1,7 @@
package envoy.server.data;
import java.time.Instant;
import java.util.List;
import java.util.*;
import java.util.logging.Level;
import javax.persistence.*;
@ -223,6 +223,9 @@ public final class PersistenceManager {
* @since Envoy Server Standalone v0.2-beta
*/
public List<Message> getPendingMessages(User user, Instant lastSync) {
if (user == null)
return new ArrayList<>();
lastSync = Objects.requireNonNullElse(lastSync, Instant.EPOCH);
return entityManager.createNamedQuery(Message.getPending).setParameter("user", user)
.setParameter("lastSeen", lastSync).getResultList();
}
@ -236,6 +239,9 @@ public final class PersistenceManager {
* @since Envoy Server Standalone v0.2-beta
*/
public List<GroupMessage> getPendingGroupMessages(User user, Instant lastSync) {
if (user == null)
return new ArrayList<>();
lastSync = Objects.requireNonNullElse(lastSync, Instant.EPOCH);
return entityManager.createNamedQuery(GroupMessage.getPendingGroupMsg)
.setParameter("userId", user.getID())
.setParameter("lastSeen", lastSync)
@ -277,16 +283,18 @@ public final class PersistenceManager {
* @since Envoy Server v0.3-beta
*/
public void addContactBidirectional(Contact contact1, Contact contact2) {
if (!(contact1 == null || contact2 == null)) {
// Add users to each others contact list
contact1.getContacts().add(contact2);
contact2.getContacts().add(contact1);
// Add users to each others contact list
contact1.getContacts().add(contact2);
contact2.getContacts().add(contact1);
// Synchronize changes with the database
transaction(() -> {
entityManager.merge(contact1);
entityManager.merge(contact2);
});
// Synchronize changes with the database
transaction(() -> {
entityManager.merge(contact1);
entityManager.merge(contact2);
});
}
}
/**
@ -308,16 +316,18 @@ public final class PersistenceManager {
* @since Envoy Server v0.3-beta
*/
public void removeContactBidirectional(Contact contact1, Contact contact2) {
if (!(contact1 == null || contact2 == null)) {
// Remove users from each others contact list
contact1.getContacts().remove(contact2);
contact2.getContacts().remove(contact1);
// Remove users from each others contact list
contact1.getContacts().remove(contact2);
contact2.getContacts().remove(contact1);
// Synchronize changes with the database
transaction(() -> {
entityManager.merge(contact1);
entityManager.merge(contact2);
});
// Synchronize changes with the database
transaction(() -> {
entityManager.merge(contact1);
entityManager.merge(contact2);
});
}
}
/**