Reformat all source files with new formatter
This commit is contained in:
@ -6,10 +6,11 @@ import java.util.logging.Level;
|
||||
|
||||
import com.jenkov.nioserver.Server;
|
||||
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import envoy.server.data.*;
|
||||
import envoy.server.net.*;
|
||||
import envoy.server.processors.*;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
/**
|
||||
* Starts the server.
|
||||
@ -27,8 +28,8 @@ public final class Startup {
|
||||
/**
|
||||
* Starts the server.
|
||||
*
|
||||
* @param args the run configuration. If it is "no-enter-to-stop" at position 0,
|
||||
* no command to read in an enter press will be generated
|
||||
* @param args the run configuration. If it is "no-enter-to-stop" at position 0, no command to
|
||||
* read in an enter press will be generated
|
||||
* @throws IOException if the server crashes
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
@ -37,32 +38,34 @@ public final class Startup {
|
||||
config.loadAll(Startup.class, "server.properties", args);
|
||||
EnvoyLog.initialize(config);
|
||||
} catch (final IllegalStateException e) {
|
||||
EnvoyLog.getLogger(Startup.class).log(Level.SEVERE, "Error loading configuration values: ", e);
|
||||
EnvoyLog.getLogger(Startup.class).log(Level.SEVERE,
|
||||
"Error loading configuration values: ", e);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
final var server = new Server(8080, ObjectMessageReader::new,
|
||||
new ObjectMessageProcessor(Set.of(new LoginCredentialProcessor(),
|
||||
new MessageProcessor(),
|
||||
new GroupMessageProcessor(),
|
||||
new GroupCreationProcessor(),
|
||||
new MessageStatusChangeProcessor(),
|
||||
new GroupMessageStatusChangeProcessor(),
|
||||
new UserStatusChangeProcessor(),
|
||||
new GroupResizeProcessor(),
|
||||
new IDGeneratorRequestProcessor(),
|
||||
new UserSearchProcessor(),
|
||||
new UserOperationProcessor(),
|
||||
new IsTypingProcessor(),
|
||||
new NameChangeProcessor(),
|
||||
new ProfilePicChangeProcessor(),
|
||||
new PasswordChangeRequestProcessor(),
|
||||
new IssueProposalProcessor())));
|
||||
new ObjectMessageProcessor(Set.of(new LoginCredentialProcessor(),
|
||||
new MessageProcessor(),
|
||||
new GroupMessageProcessor(),
|
||||
new GroupCreationProcessor(),
|
||||
new MessageStatusChangeProcessor(),
|
||||
new GroupMessageStatusChangeProcessor(),
|
||||
new UserStatusChangeProcessor(),
|
||||
new GroupResizeProcessor(),
|
||||
new IDGeneratorRequestProcessor(),
|
||||
new UserSearchProcessor(),
|
||||
new UserOperationProcessor(),
|
||||
new IsTypingProcessor(),
|
||||
new NameChangeProcessor(),
|
||||
new ProfilePicChangeProcessor(),
|
||||
new PasswordChangeRequestProcessor(),
|
||||
new IssueProposalProcessor())));
|
||||
|
||||
// Initialize the current message ID
|
||||
final var persistenceManager = PersistenceManager.getInstance();
|
||||
if (persistenceManager.getConfigItemByID("currentMessageId") == null)
|
||||
persistenceManager.addConfigItem(new envoy.server.data.ConfigItem("currentMessageId", "0"));
|
||||
persistenceManager
|
||||
.addConfigItem(new envoy.server.data.ConfigItem("currentMessageId", "0"));
|
||||
|
||||
server.start();
|
||||
server.getSocketProcessor().registerSocketIdListener(ConnectionManager.getInstance());
|
||||
|
@ -6,8 +6,7 @@ import java.util.Set;
|
||||
import javax.persistence.*;
|
||||
|
||||
/**
|
||||
* This class acts as a superclass for all contacts, being {@link User}s and
|
||||
* {@link Group}s.
|
||||
* This class acts as a superclass for all contacts, being {@link User}s and {@link Group}s.
|
||||
*
|
||||
* @author Maximilian Käfer
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
@ -30,18 +29,16 @@ public abstract class Contact {
|
||||
protected Set<Contact> contacts;
|
||||
|
||||
/**
|
||||
* @return a {@link envoy.data.Contact} object of this envoy.server.data.Contact
|
||||
* object.
|
||||
* @return a {@link envoy.data.Contact} object of this envoy.server.data.Contact object.
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
public abstract envoy.data.Contact toCommon();
|
||||
|
||||
/**
|
||||
* Transforms this contact into a {@link envoy.data.Contact} where the contacts
|
||||
* set of contacts is empty.
|
||||
* Transforms this contact into a {@link envoy.data.Contact} where the contacts set of contacts
|
||||
* is empty.
|
||||
*
|
||||
* @return a {@link envoy.data.Contact} object of this contact
|
||||
* object.
|
||||
* @return a {@link envoy.data.Contact} object of this contact object.
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
protected abstract envoy.data.Contact toFlatCommon();
|
||||
@ -99,5 +96,8 @@ public abstract class Contact {
|
||||
public void setCreationDate(Instant creationDate) { this.creationDate = creationDate; }
|
||||
|
||||
@Override
|
||||
public String toString() { return String.format("%s[id=%d,name=%s,%d contact(s)]", getClass().getSimpleName(), id, name, contacts.size()); }
|
||||
public String toString() {
|
||||
return String.format("%s[id=%d,name=%s,%d contact(s)]", getClass().getSimpleName(), id,
|
||||
name, contacts.size());
|
||||
}
|
||||
}
|
||||
|
@ -5,22 +5,16 @@ import java.util.stream.Collectors;
|
||||
import javax.persistence.*;
|
||||
|
||||
/**
|
||||
* Represents a group inside the database. Referred to as "server group" as
|
||||
* opposed to "group" from Envoy Common.
|
||||
* Represents a group inside the database. Referred to as "server group" as opposed to "group" from
|
||||
* Envoy Common.
|
||||
*
|
||||
* @author Maximilian Käfer
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
@Entity
|
||||
@NamedQueries({
|
||||
@NamedQuery(
|
||||
name = Group.findByName,
|
||||
query = "SELECT g FROM Group g WHERE g.name = :name"
|
||||
),
|
||||
@NamedQuery(
|
||||
name = Group.findPendingGroups,
|
||||
query = "SELECT g FROM Group g WHERE g.creationDate > :lastSeen AND :user MEMBER OF g.contacts"
|
||||
)
|
||||
@NamedQuery(name = Group.findByName, query = "SELECT g FROM Group g WHERE g.name = :name"),
|
||||
@NamedQuery(name = Group.findPendingGroups, query = "SELECT g FROM Group g WHERE g.creationDate > :lastSeen AND :user MEMBER OF g.contacts")
|
||||
})
|
||||
public final class Group extends Contact {
|
||||
|
||||
@ -32,7 +26,8 @@ public final class Group extends Contact {
|
||||
public static final String findByName = "Group.findByName";
|
||||
|
||||
/**
|
||||
* Named query retrieving all pending groups for a specific user (parameter {@code :user}, {@code :lastSeen}).
|
||||
* Named query retrieving all pending groups for a specific user (parameter {@code :user},
|
||||
* {@code :lastSeen}).
|
||||
*
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
@ -40,9 +35,12 @@ public final class Group extends Contact {
|
||||
|
||||
@Override
|
||||
public envoy.data.Group toCommon() {
|
||||
return new envoy.data.Group(id, name, contacts.parallelStream().map(User.class::cast).map(User::toFlatCommon).collect(Collectors.toSet()));
|
||||
return new envoy.data.Group(id, name, contacts.parallelStream().map(User.class::cast)
|
||||
.map(User::toFlatCommon).collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected envoy.data.Group toFlatCommon() { return toCommon(); }
|
||||
protected envoy.data.Group toFlatCommon() {
|
||||
return toCommon();
|
||||
}
|
||||
}
|
||||
|
@ -12,20 +12,17 @@ import envoy.data.Group;
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
@Entity
|
||||
@NamedQuery(
|
||||
name = GroupMessage.getPendingGroupMsg,
|
||||
query = "SELECT m FROM GroupMessage m JOIN m.memberMessageStatus s WHERE KEY(s) = :userId AND (m.creationDate > :lastSeen "
|
||||
+ "OR m.status = envoy.data.Message$MessageStatus.RECEIVED AND m.receivedDate > :lastSeen "
|
||||
+ "OR m.status = envoy.data.Message$MessageStatus.READ AND m.readDate > :lastSeen "
|
||||
+ "OR m.lastStatusChangeDate > :lastSeen)"
|
||||
)
|
||||
@NamedQuery(name = GroupMessage.getPendingGroupMsg, query = "SELECT m FROM GroupMessage m JOIN m.memberMessageStatus s WHERE KEY(s) = :userId AND (m.creationDate > :lastSeen "
|
||||
+ "OR m.status = envoy.data.Message$MessageStatus.RECEIVED AND m.receivedDate > :lastSeen "
|
||||
+ "OR m.status = envoy.data.Message$MessageStatus.READ AND m.readDate > :lastSeen "
|
||||
+ "OR m.lastStatusChangeDate > :lastSeen)")
|
||||
public final class GroupMessage extends Message {
|
||||
|
||||
/**
|
||||
* Named query retrieving pending group messages sent to a group containing a
|
||||
* specific user (parameter {@code userId}) that were sent after a certain time
|
||||
* stamp (parameter {@code :lastSeen}).
|
||||
*
|
||||
* Named query retrieving pending group messages sent to a group containing a specific user
|
||||
* (parameter {@code userId}) that were sent after a certain time stamp (parameter
|
||||
* {@code :lastSeen}).
|
||||
*
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
public static final String getPendingGroupMsg = "GroupMessage.getPendingGroupMsg";
|
||||
@ -46,9 +43,8 @@ public final class GroupMessage extends Message {
|
||||
/**
|
||||
* Constructs a database groupMessage from a common groupMessage.
|
||||
*
|
||||
* @param groupMessage the {@link envoy.data.GroupMessage} to convert
|
||||
* into a
|
||||
* database {@link GroupMessage}
|
||||
* @param groupMessage the {@link envoy.data.GroupMessage} to convert into a database
|
||||
* {@link GroupMessage}
|
||||
* @param lastStatusChangeDate the time stamp to set
|
||||
* @since Envoy Server Standalone v0.2-beta
|
||||
*/
|
||||
@ -59,29 +55,31 @@ public final class GroupMessage extends Message {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this groupMessage into an instance of
|
||||
* {@link envoy.data.GroupMessage}.
|
||||
* Converts this groupMessage into an instance of {@link envoy.data.GroupMessage}.
|
||||
*
|
||||
* @return a {@link envoy.data.GroupMessage} containing the same values as this
|
||||
* groupMessage
|
||||
* @return a {@link envoy.data.GroupMessage} containing the same values as this groupMessage
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
@Override
|
||||
public envoy.data.GroupMessage toCommon() {
|
||||
return prepareBuilder().buildGroupMessage((Group) recipient.toCommon(), new HashMap<>(memberMessageStatus));
|
||||
return prepareBuilder().buildGroupMessage((Group) recipient.toCommon(),
|
||||
new HashMap<>(memberMessageStatus));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the memberMessageStatus
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
public Map<Long, envoy.data.Message.MessageStatus> getMemberMessageStatus() { return memberMessageStatus; }
|
||||
public Map<Long, envoy.data.Message.MessageStatus> getMemberMessageStatus() {
|
||||
return memberMessageStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param memberMessageStatus the memberMessageStatus to set
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
public void setMemberMessageStatus(Map<Long, envoy.data.Message.MessageStatus> memberMessageStatus) {
|
||||
public void setMemberMessageStatus(
|
||||
Map<Long, envoy.data.Message.MessageStatus> memberMessageStatus) {
|
||||
this.memberMessageStatus = memberMessageStatus;
|
||||
}
|
||||
|
||||
|
@ -12,14 +12,14 @@ import envoy.data.Attachment.AttachmentType;
|
||||
import envoy.data.Message.MessageStatus;
|
||||
|
||||
/**
|
||||
* This JPA entity, which will be referred to as database message, stores the
|
||||
* information contained inside a {@link envoy.data.Message} inside the
|
||||
* database, while having a slightly different data layout.
|
||||
* This JPA entity, which will be referred to as database message, stores the information contained
|
||||
* inside a {@link envoy.data.Message} inside the database, while having a slightly different data
|
||||
* layout.
|
||||
* <p>
|
||||
* A message can be converted to a database message by using the
|
||||
* {@link Message#Message(envoy.data.Message)} constructor. A database message
|
||||
* can be converted to a regular message using the {@link Message#toCommon()}
|
||||
* method. In both cases, the objects will not contain references to each other.
|
||||
* {@link Message#Message(envoy.data.Message)} constructor. A database message can be converted to a
|
||||
* regular message using the {@link Message#toCommon()} method. In both cases, the objects will not
|
||||
* contain references to each other.
|
||||
*
|
||||
* @author Kai S. K. Engelbart
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
@ -27,22 +27,19 @@ import envoy.data.Message.MessageStatus;
|
||||
@Entity
|
||||
@Table(name = "messages")
|
||||
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
|
||||
@NamedQuery(
|
||||
name = Message.getPending,
|
||||
query = "SELECT m FROM Message m WHERE "
|
||||
// Send to or by the user before last seen
|
||||
+ "(m.sender = :user OR m.recipient = :user) AND m.creationDate > :lastSeen "
|
||||
// SENT to the user
|
||||
+ "OR m.recipient = :user AND m.status = envoy.data.Message$MessageStatus.SENT "
|
||||
// Sent by the user and RECEIVED / READ after last seen
|
||||
+ "OR m.sender = :user AND (m.status = envoy.data.Message$MessageStatus.RECEIVED AND m.receivedDate > :lastSeen "
|
||||
+ "OR m.status = envoy.data.Message$MessageStatus.READ AND m.readDate > :lastSeen)"
|
||||
)
|
||||
@NamedQuery(name = Message.getPending, query = "SELECT m FROM Message m WHERE "
|
||||
// Send to or by the user before last seen
|
||||
+ "(m.sender = :user OR m.recipient = :user) AND m.creationDate > :lastSeen "
|
||||
// SENT to the user
|
||||
+ "OR m.recipient = :user AND m.status = envoy.data.Message$MessageStatus.SENT "
|
||||
// Sent by the user and RECEIVED / READ after last seen
|
||||
+ "OR m.sender = :user AND (m.status = envoy.data.Message$MessageStatus.RECEIVED AND m.receivedDate > :lastSeen "
|
||||
+ "OR m.status = envoy.data.Message$MessageStatus.READ AND m.readDate > :lastSeen)")
|
||||
public class Message {
|
||||
|
||||
/**
|
||||
* Named query retrieving pending messages for a user (parameter {@code :user})
|
||||
* which was last seen after a specific date (parameter {@code :lastSeen}).
|
||||
* Named query retrieving pending messages for a user (parameter {@code :user}) which was last
|
||||
* seen after a specific date (parameter {@code :lastSeen}).
|
||||
*
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
@ -85,8 +82,7 @@ public class Message {
|
||||
/**
|
||||
* Constructs a database message from a common message.
|
||||
*
|
||||
* @param message the {@link envoy.data.Message} to convert into a database
|
||||
* {@link Message}
|
||||
* @param message the {@link envoy.data.Message} to convert into a database {@link Message}
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public Message(envoy.data.Message message) {
|
||||
@ -111,11 +107,12 @@ public class Message {
|
||||
/**
|
||||
* Converts this message into an instance of {@link envoy.data.Message}.
|
||||
*
|
||||
* @return a {@link envoy.data.Message} containing the same values as this
|
||||
* message
|
||||
* @return a {@link envoy.data.Message} containing the same values as this message
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public envoy.data.Message toCommon() { return prepareBuilder().build(); }
|
||||
public envoy.data.Message toCommon() {
|
||||
return prepareBuilder().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a message builder containing the state of this message
|
||||
@ -128,13 +125,14 @@ public class Message {
|
||||
.setReadDate(readDate)
|
||||
.setStatus(status)
|
||||
.setForwarded(forwarded);
|
||||
if (attachment != null) builder.setAttachment(new Attachment(attachment, attachmentName, attachmentType));
|
||||
if (attachment != null)
|
||||
builder.setAttachment(new Attachment(attachment, attachmentName, attachmentType));
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message status to {@link MessageStatus#RECEIVED} and sets the
|
||||
* current time stamp as the received date.
|
||||
* Sets the message status to {@link MessageStatus#RECEIVED} and sets the current time stamp as
|
||||
* the received date.
|
||||
*
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
@ -144,8 +142,8 @@ public class Message {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message status to {@link MessageStatus#READ} and sets the
|
||||
* current time stamp as the read date.
|
||||
* Sets the message status to {@link MessageStatus#READ} and sets the current time stamp as the
|
||||
* read date.
|
||||
*
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
@ -207,8 +205,7 @@ public class Message {
|
||||
public void setCreationDate(Instant creationDate) { this.creationDate = creationDate; }
|
||||
|
||||
/**
|
||||
* @return the date at which a {link envoy.data.Message} has been received by
|
||||
* the server
|
||||
* @return the date at which a {link envoy.data.Message} has been received by the server
|
||||
* @since Envoy Server Standalone v0.2-beta
|
||||
*/
|
||||
public Instant getReceivedDate() { return receivedDate; }
|
||||
@ -279,7 +276,9 @@ public class Message {
|
||||
* @param attachmentType the attachmentType to set
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
public void setAttachmentType(AttachmentType attachmentType) { this.attachmentType = attachmentType; }
|
||||
public void setAttachmentType(AttachmentType attachmentType) {
|
||||
this.attachmentType = attachmentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the attachmentName
|
||||
@ -291,7 +290,9 @@ public class Message {
|
||||
* @param attachmentName the attachmentName to set
|
||||
* @since Envoy Server v0.2-beta
|
||||
*/
|
||||
public void setAttachmentName(String attachmentName) { this.attachmentName = attachmentName; }
|
||||
public void setAttachmentName(String attachmentName) {
|
||||
this.attachmentName = attachmentName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether this message is a forwarded message
|
||||
|
@ -7,9 +7,10 @@ import java.util.logging.Level;
|
||||
import javax.persistence.*;
|
||||
|
||||
import envoy.data.User.UserStatus;
|
||||
import envoy.server.net.ConnectionManager;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import envoy.server.net.ConnectionManager;
|
||||
|
||||
/**
|
||||
* Contains operations used for persistence.
|
||||
*
|
||||
@ -19,7 +20,8 @@ import envoy.util.EnvoyLog;
|
||||
*/
|
||||
public final class PersistenceManager {
|
||||
|
||||
private final EntityManager entityManager = Persistence.createEntityManagerFactory("envoy").createEntityManager();
|
||||
private final EntityManager entityManager =
|
||||
Persistence.createEntityManagerFactory("envoy").createEntityManager();
|
||||
private final EntityTransaction transaction = entityManager.getTransaction();
|
||||
|
||||
private static final PersistenceManager persistenceManager = new PersistenceManager();
|
||||
@ -35,7 +37,11 @@ public final class PersistenceManager {
|
||||
.getOnlineUsers()
|
||||
.stream()
|
||||
.map(this::getUserByID)
|
||||
.forEach(user -> { user.setStatus(UserStatus.OFFLINE); user.setLastSeen(Instant.now()); entityManager.merge(user); });
|
||||
.forEach(user -> {
|
||||
user.setStatus(UserStatus.OFFLINE);
|
||||
user.setLastSeen(Instant.now());
|
||||
entityManager.merge(user);
|
||||
});
|
||||
})));
|
||||
}
|
||||
|
||||
@ -51,7 +57,9 @@ public final class PersistenceManager {
|
||||
* @param contact the {@link Contact} to add to the database
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public void addContact(Contact contact) { persist(contact); }
|
||||
public void addContact(Contact contact) {
|
||||
persist(contact);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link Message} to the database.
|
||||
@ -59,7 +67,9 @@ public final class PersistenceManager {
|
||||
* @param message the {@link Message} to add to the database
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public void addMessage(Message message) { persist(message); }
|
||||
public void addMessage(Message message) {
|
||||
persist(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link ConfigItem} to the database.
|
||||
@ -67,7 +77,9 @@ public final class PersistenceManager {
|
||||
* @param configItem the {@link ConfigItem} to add to the database
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public void addConfigItem(ConfigItem configItem) { persist(configItem); }
|
||||
public void addConfigItem(ConfigItem configItem) {
|
||||
persist(configItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a {@link Contact} in the database
|
||||
@ -75,7 +87,9 @@ public final class PersistenceManager {
|
||||
* @param contact the {@link Contact} to add to the database
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public void updateContact(Contact contact) { merge(contact); }
|
||||
public void updateContact(Contact contact) {
|
||||
merge(contact);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a {@link Message} in the database.
|
||||
@ -83,7 +97,9 @@ public final class PersistenceManager {
|
||||
* @param message the message to update
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public void updateMessage(Message message) { merge(message); }
|
||||
public void updateMessage(Message message) {
|
||||
merge(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a {@link ConfigItem} in the database.
|
||||
@ -91,7 +107,9 @@ public final class PersistenceManager {
|
||||
* @param configItem the configItem to update
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public void updateConfigItem(ConfigItem configItem) { merge(configItem); }
|
||||
public void updateConfigItem(ConfigItem configItem) {
|
||||
merge(configItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a {@link Contact} in the database.
|
||||
@ -115,7 +133,9 @@ public final class PersistenceManager {
|
||||
* @param message the {@link Message} to delete
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public void deleteMessage(Message message) { remove(message); }
|
||||
public void deleteMessage(Message message) {
|
||||
remove(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for a {@link User} with a specific ID.
|
||||
@ -124,7 +144,9 @@ public final class PersistenceManager {
|
||||
* @return the user with the specified ID or {@code null} if none was found
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public User getUserByID(long id) { return entityManager.find(User.class, id); }
|
||||
public User getUserByID(long id) {
|
||||
return entityManager.find(User.class, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for a {@link Group} with a specific ID.
|
||||
@ -133,7 +155,9 @@ public final class PersistenceManager {
|
||||
* @return the group with the specified ID or {@code null} if none was found
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
public Group getGroupByID(long id) { return entityManager.find(Group.class, id); }
|
||||
public Group getGroupByID(long id) {
|
||||
return entityManager.find(Group.class, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for a {@link Contact} with a specific ID.
|
||||
@ -142,7 +166,9 @@ public final class PersistenceManager {
|
||||
* @return the contact with the specified ID or {@code null} if none was found
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
public Contact getContactByID(long id) { return entityManager.find(Contact.class, id); }
|
||||
public Contact getContactByID(long id) {
|
||||
return entityManager.find(Contact.class, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searched for a {@link User} with a specific name.
|
||||
@ -152,7 +178,8 @@ public final class PersistenceManager {
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public User getUserByName(String name) {
|
||||
return (User) entityManager.createNamedQuery(User.findByName).setParameter("name", name).getSingleResult();
|
||||
return (User) entityManager.createNamedQuery(User.findByName).setParameter("name", name)
|
||||
.getSingleResult();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,7 +190,8 @@ public final class PersistenceManager {
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public Group getGroupByName(String name) {
|
||||
return (Group) entityManager.createNamedQuery(Group.findByName).setParameter("name", name).getSingleResult();
|
||||
return (Group) entityManager.createNamedQuery(Group.findByName).setParameter("name", name)
|
||||
.getSingleResult();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,18 +201,21 @@ public final class PersistenceManager {
|
||||
* @return the message with the specified ID or {@code null} if none is found
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public Message getMessageByID(long id) { return entityManager.find(Message.class, id); }
|
||||
public Message getMessageByID(long id) {
|
||||
return entityManager.find(Message.class, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key the name of this {@link ConfigItem}
|
||||
* @return the {@link ConfigItem} with the given name
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public ConfigItem getConfigItemByID(String key) { return entityManager.find(ConfigItem.class, key); }
|
||||
public ConfigItem getConfigItemByID(String key) {
|
||||
return entityManager.find(ConfigItem.class, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all messages received while being offline or the ones that have
|
||||
* changed.
|
||||
* Returns all messages received while being offline or the ones that have changed.
|
||||
*
|
||||
* @param user the user who wants to receive his unread messages
|
||||
* @param lastSync the time stamp of the last synchronization
|
||||
@ -192,17 +223,16 @@ public final class PersistenceManager {
|
||||
* @since Envoy Server Standalone v0.2-beta
|
||||
*/
|
||||
public List<Message> getPendingMessages(User user, Instant lastSync) {
|
||||
return entityManager.createNamedQuery(Message.getPending).setParameter("user", user).setParameter("lastSeen", lastSync).getResultList();
|
||||
return entityManager.createNamedQuery(Message.getPending).setParameter("user", user)
|
||||
.setParameter("lastSeen", lastSync).getResultList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all groupMessages received while being offline or the ones that have
|
||||
* changed.
|
||||
* Returns all groupMessages received while being offline or the ones that have changed.
|
||||
*
|
||||
* @param user the user who wants to receive his unread groupMessages
|
||||
* @param lastSync the time stamp of the last synchronization
|
||||
* @return all groupMessages that the client does not yet have (unread
|
||||
* groupMessages)
|
||||
* @return all groupMessages that the client does not yet have (unread groupMessages)
|
||||
* @since Envoy Server Standalone v0.2-beta
|
||||
*/
|
||||
public List<GroupMessage> getPendingGroupMessages(User user, Instant lastSync) {
|
||||
@ -213,12 +243,11 @@ public final class PersistenceManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for users matching a search phrase. Contacts of the attached user
|
||||
* and the attached user is ignored.
|
||||
* Searches for users matching a search phrase. Contacts of the attached user and the attached
|
||||
* user is ignored.
|
||||
*
|
||||
* @param searchPhrase the search phrase
|
||||
* @param userId the ID of the user in whose context the search is
|
||||
* performed
|
||||
* @param userId the ID of the user in whose context the search is performed
|
||||
* @return a list of all users who matched the criteria
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
@ -254,7 +283,10 @@ public final class PersistenceManager {
|
||||
contact2.getContacts().add(contact1);
|
||||
|
||||
// Synchronize changes with the database
|
||||
transaction(() -> { entityManager.merge(contact1); entityManager.merge(contact2); });
|
||||
transaction(() -> {
|
||||
entityManager.merge(contact1);
|
||||
entityManager.merge(contact2);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -282,7 +314,10 @@ public final class PersistenceManager {
|
||||
contact2.getContacts().remove(contact1);
|
||||
|
||||
// Synchronize changes with the database
|
||||
transaction(() -> { entityManager.merge(contact1); entityManager.merge(contact2); });
|
||||
transaction(() -> {
|
||||
entityManager.merge(contact1);
|
||||
entityManager.merge(contact2);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -291,21 +326,27 @@ public final class PersistenceManager {
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public List<User> getContacts(User user) {
|
||||
return entityManager.createNamedQuery(User.findContacts).setParameter("user", user).getResultList();
|
||||
return entityManager.createNamedQuery(User.findContacts).setParameter("user", user)
|
||||
.getResultList();
|
||||
}
|
||||
|
||||
private void persist(Object obj) { transaction(() -> entityManager.persist(obj)); }
|
||||
private void persist(Object obj) {
|
||||
transaction(() -> entityManager.persist(obj));
|
||||
}
|
||||
|
||||
private void merge(Object obj) { transaction(() -> entityManager.merge(obj)); }
|
||||
private void merge(Object obj) {
|
||||
transaction(() -> entityManager.merge(obj));
|
||||
}
|
||||
|
||||
private void remove(Object obj) { transaction(() -> entityManager.remove(obj)); }
|
||||
private void remove(Object obj) {
|
||||
transaction(() -> entityManager.remove(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a transaction with the given Runnable, that should somewhere call
|
||||
* {@link EntityManager}.
|
||||
*
|
||||
* @param entityManagerRelatedAction the action that changes something in the
|
||||
* database
|
||||
* @param entityManagerRelatedAction the action that changes something in the database
|
||||
* @since Envoy Server v0.3-beta
|
||||
*/
|
||||
private void transaction(Runnable entityManagerRelatedAction) {
|
||||
@ -328,8 +369,10 @@ public final class PersistenceManager {
|
||||
if (transaction.isActive()) {
|
||||
transaction.rollback();
|
||||
EnvoyLog.getLogger(PersistenceManager.class)
|
||||
.log(Level.SEVERE, "Could not perform transaction, hence discarding it. It's likely that a serious issue exists.");
|
||||
} else throw e2;
|
||||
.log(Level.SEVERE,
|
||||
"Could not perform transaction, hence discarding it. It's likely that a serious issue exists.");
|
||||
} else
|
||||
throw e2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,9 @@ public final class ServerConfig extends Config {
|
||||
* @return the singleton instance of the server config
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public static ServerConfig getInstance() { return config == null ? config = new ServerConfig() : config; }
|
||||
public static ServerConfig getInstance() {
|
||||
return config == null ? config = new ServerConfig() : config;
|
||||
}
|
||||
|
||||
private ServerConfig() {
|
||||
super(".envoy-server");
|
||||
@ -45,13 +47,17 @@ public final class ServerConfig extends Config {
|
||||
* @return {@code true} if issue reporting is enabled
|
||||
* @since Envoy Client v0.3-alpha
|
||||
*/
|
||||
public Boolean isIssueReportingEnabled() { return (Boolean) items.get("enableIssueReporting").get(); }
|
||||
public Boolean isIssueReportingEnabled() {
|
||||
return (Boolean) items.get("enableIssueReporting").get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if attachment support has been enabled
|
||||
* @since Envoy Client v0.3-alpha
|
||||
*/
|
||||
public Boolean isAttachmentSupportEnabled() { return (Boolean) items.get("enableAttachments").get(); }
|
||||
public Boolean isAttachmentSupportEnabled() {
|
||||
return (Boolean) items.get("enableAttachments").get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if group support has been enabled
|
||||
@ -85,9 +91,8 @@ public final class ServerConfig extends Config {
|
||||
|
||||
/**
|
||||
* @return the authorization token used to authenticate to
|
||||
* {@link ServerConfig#getIssueReportingURL()}. If null,
|
||||
* authorization is expected to occur via a query_param or via a basic
|
||||
* user-password-combination
|
||||
* {@link ServerConfig#getIssueReportingURL()}. If null, authorization is expected to
|
||||
* occur via a query_param or via a basic user-password-combination
|
||||
* @since Envoy Server v0.2-beta
|
||||
*/
|
||||
public String getIssueAuthToken() { return (String) items.get("issueAuthToken").get(); }
|
||||
@ -96,5 +101,7 @@ public final class ServerConfig extends Config {
|
||||
* @return the amount of days after which user authentication tokens expire
|
||||
* @since Envoy Server v0.2-beta
|
||||
*/
|
||||
public Integer getAuthTokenExpiration() { return (Integer) items.get("authTokenExpiration").get(); }
|
||||
public Integer getAuthTokenExpiration() {
|
||||
return (Integer) items.get("authTokenExpiration").get();
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,9 @@ import javax.persistence.*;
|
||||
import envoy.data.User.UserStatus;
|
||||
|
||||
/**
|
||||
* This class enables the storage of user specific data inside a database using
|
||||
* Hibernate. Its objects will be referred to as database users as opposed to
|
||||
* the common user objects present on both the client and the server.
|
||||
* This class enables the storage of user specific data inside a database using Hibernate. Its
|
||||
* objects will be referred to as database users as opposed to the common user objects present on
|
||||
* both the client and the server.
|
||||
*
|
||||
* @author Kai S. K. Engelbart
|
||||
* @author Maximilian Käfer
|
||||
@ -19,18 +19,9 @@ import envoy.data.User.UserStatus;
|
||||
*/
|
||||
@Entity
|
||||
@NamedQueries({
|
||||
@NamedQuery(
|
||||
name = User.findByName,
|
||||
query = "SELECT u FROM User u WHERE u.name = :name"
|
||||
),
|
||||
@NamedQuery(
|
||||
name = User.findContacts,
|
||||
query = "SELECT u.contacts FROM User u WHERE u = :user"
|
||||
),
|
||||
@NamedQuery(
|
||||
name = User.searchByName,
|
||||
query = "SELECT u FROM User u WHERE (lower(u.name) LIKE lower(:searchPhrase) AND u <> :context AND :context NOT MEMBER OF u.contacts)"
|
||||
)
|
||||
@NamedQuery(name = User.findByName, query = "SELECT u FROM User u WHERE u.name = :name"),
|
||||
@NamedQuery(name = User.findContacts, query = "SELECT u.contacts FROM User u WHERE u = :user"),
|
||||
@NamedQuery(name = User.searchByName, query = "SELECT u FROM User u WHERE (lower(u.name) LIKE lower(:searchPhrase) AND u <> :context AND :context NOT MEMBER OF u.contacts)")
|
||||
})
|
||||
public final class User extends Contact {
|
||||
|
||||
@ -42,8 +33,7 @@ public final class User extends Contact {
|
||||
public static final String findByName = "User.findByName";
|
||||
|
||||
/**
|
||||
* Named query retrieving the contacts of a given user (parameter
|
||||
* {@code :user}).
|
||||
* Named query retrieving the contacts of a given user (parameter {@code :user}).
|
||||
*
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
@ -51,8 +41,8 @@ public final class User extends Contact {
|
||||
|
||||
/**
|
||||
* Named query searching for users with a name like a search phrase (parameter
|
||||
* {@code :searchPhrase}) that are not in the contact list of a given user
|
||||
* (parameter {@code :context}).
|
||||
* {@code :searchPhrase}) that are not in the contact list of a given user (parameter
|
||||
* {@code :context}).
|
||||
*
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
@ -77,11 +67,14 @@ public final class User extends Contact {
|
||||
|
||||
@Override
|
||||
public envoy.data.User toCommon() {
|
||||
return new envoy.data.User(id, name, status, contacts.parallelStream().map(Contact::toFlatCommon).collect(Collectors.toSet()));
|
||||
return new envoy.data.User(id, name, status,
|
||||
contacts.parallelStream().map(Contact::toFlatCommon).collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected envoy.data.User toFlatCommon() { return new envoy.data.User(id, name, status, Set.of()); }
|
||||
protected envoy.data.User toFlatCommon() {
|
||||
return new envoy.data.User(id, name, status, Set.of());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the password hash
|
||||
@ -114,11 +107,12 @@ public final class User extends Contact {
|
||||
public Instant getAuthTokenExpiration() { return authTokenExpiration; }
|
||||
|
||||
/**
|
||||
* @param authTokenExpiration the authentication token expiration timestamp to
|
||||
* set
|
||||
* @param authTokenExpiration the authentication token expiration timestamp to set
|
||||
* @since Envoy Server v0.2-beta
|
||||
*/
|
||||
public void setAuthTokenExpiration(Instant authTokenExpiration) { this.authTokenExpiration = authTokenExpiration; }
|
||||
public void setAuthTokenExpiration(Instant authTokenExpiration) {
|
||||
this.authTokenExpiration = authTokenExpiration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the last date the user has been online
|
||||
@ -154,5 +148,7 @@ public final class User extends Contact {
|
||||
* @param latestContactDeletion the latestContactDeletion to set
|
||||
* @since Envoy Server v0.3-beta
|
||||
*/
|
||||
public void setLatestContactDeletion(Instant latestContactDeletion) { this.latestContactDeletion = latestContactDeletion; }
|
||||
public void setLatestContactDeletion(Instant latestContactDeletion) {
|
||||
this.latestContactDeletion = latestContactDeletion;
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import java.util.stream.Collectors;
|
||||
import com.jenkov.nioserver.ISocketIdListener;
|
||||
|
||||
import envoy.data.User.UserStatus;
|
||||
|
||||
import envoy.server.data.*;
|
||||
import envoy.server.processors.UserStatusChangeProcessor;
|
||||
|
||||
@ -17,8 +18,8 @@ import envoy.server.processors.UserStatusChangeProcessor;
|
||||
public final class ConnectionManager implements ISocketIdListener {
|
||||
|
||||
/**
|
||||
* Contains all socket IDs that have not yet performed a handshake / acquired
|
||||
* their corresponding user ID.
|
||||
* Contains all socket IDs that have not yet performed a handshake / acquired their
|
||||
* corresponding user ID.
|
||||
*
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
@ -46,7 +47,8 @@ public final class ConnectionManager implements ISocketIdListener {
|
||||
if (!pendingSockets.remove(socketID)) {
|
||||
|
||||
// Notify contacts of this users offline-going
|
||||
final envoy.server.data.User user = PersistenceManager.getInstance().getUserByID(getUserIDBySocketID(socketID));
|
||||
final envoy.server.data.User user =
|
||||
PersistenceManager.getInstance().getUserByID(getUserIDBySocketID(socketID));
|
||||
user.setLastSeen(Instant.now());
|
||||
UserStatusChangeProcessor.updateUserStatus(user, UserStatus.OFFLINE);
|
||||
|
||||
@ -56,7 +58,9 @@ public final class ConnectionManager implements ISocketIdListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void socketRegistered(long socketID) { pendingSockets.add(socketID); }
|
||||
public void socketRegistered(long socketID) {
|
||||
pendingSockets.add(socketID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates a socket ID with a user ID.
|
||||
@ -75,7 +79,9 @@ public final class ConnectionManager implements ISocketIdListener {
|
||||
* @return the ID of the socket
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public long getSocketID(long userID) { return sockets.get(userID); }
|
||||
public long getSocketID(long userID) {
|
||||
return sockets.get(userID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param socketID the id of the socket whose User is needed
|
||||
@ -83,7 +89,8 @@ public final class ConnectionManager implements ISocketIdListener {
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public long getUserIDBySocketID(long socketID) {
|
||||
return sockets.entrySet().stream().filter(entry -> entry.getValue().equals(socketID)).findFirst().get().getKey();
|
||||
return sockets.entrySet().stream().filter(entry -> entry.getValue().equals(socketID))
|
||||
.findFirst().get().getKey();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,7 +98,9 @@ public final class ConnectionManager implements ISocketIdListener {
|
||||
* @return {@code true} if the user is online
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public boolean isOnline(long userID) { return sockets.containsKey(userID); }
|
||||
public boolean isOnline(long userID) {
|
||||
return sockets.containsKey(userID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the userIDs of all users who are currently online
|
||||
@ -105,6 +114,7 @@ public final class ConnectionManager implements ISocketIdListener {
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
public Set<Long> getOnlineUsersOfGroup(Group group) {
|
||||
return group.getContacts().stream().map(Contact::getID).filter(this::isOnline).collect(Collectors.toSet());
|
||||
return group.getContacts().stream().map(Contact::getID).filter(this::isOnline)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,10 @@ import java.util.logging.*;
|
||||
|
||||
import com.jenkov.nioserver.*;
|
||||
|
||||
import envoy.server.processors.ObjectProcessor;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import envoy.server.processors.ObjectProcessor;
|
||||
|
||||
/**
|
||||
* Handles incoming objects.
|
||||
*
|
||||
@ -28,12 +29,16 @@ public final class ObjectMessageProcessor implements IMessageProcessor {
|
||||
* @param processors the {@link ObjectProcessor} to set
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public ObjectMessageProcessor(Set<ObjectProcessor<?>> processors) { this.processors = processors; }
|
||||
public ObjectMessageProcessor(Set<ObjectProcessor<?>> processors) {
|
||||
this.processors = processors;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void process(Message message, WriteProxy writeProxy) {
|
||||
try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(message.sharedArray, message.offset + 4, message.length - 4))) {
|
||||
try (ObjectInputStream in =
|
||||
new ObjectInputStream(new ByteArrayInputStream(message.sharedArray, message.offset + 4,
|
||||
message.length - 4))) {
|
||||
Object obj = in.readObject();
|
||||
if (obj == null) {
|
||||
logger.warning("Received a null object");
|
||||
@ -45,7 +50,8 @@ public final class ObjectMessageProcessor implements IMessageProcessor {
|
||||
// Get processor and input class and process object
|
||||
for (@SuppressWarnings("rawtypes")
|
||||
ObjectProcessor p : processors) {
|
||||
Class<?> c = (Class<?>) ((ParameterizedType) p.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0];
|
||||
Class<?> c = (Class<?>) ((ParameterizedType) p.getClass().getGenericInterfaces()[0])
|
||||
.getActualTypeArguments()[0];
|
||||
if (c.equals(obj.getClass()))
|
||||
try {
|
||||
p.process(c.cast(obj), message.socketId, new ObjectWriteProxy(writeProxy));
|
||||
|
@ -16,9 +16,9 @@ import envoy.util.SerializationUtils;
|
||||
*/
|
||||
public final class ObjectMessageReader implements IMessageReader {
|
||||
|
||||
private List<Message> completeMessages = new ArrayList<>();
|
||||
private Message nextMessage;
|
||||
private MessageBuffer messageBuffer;
|
||||
private final List<Message> completeMessages = new ArrayList<>();
|
||||
private Message nextMessage;
|
||||
private MessageBuffer messageBuffer;
|
||||
|
||||
@Override
|
||||
public List<Message> getMessages() { return completeMessages; }
|
||||
@ -43,7 +43,8 @@ public final class ObjectMessageReader implements IMessageReader {
|
||||
buffer.clear();
|
||||
|
||||
// Get message length
|
||||
if (nextMessage.length < 4) return;
|
||||
if (nextMessage.length < 4)
|
||||
return;
|
||||
int length = SerializationUtils.bytesToInt(nextMessage.sharedArray, nextMessage.offset) + 4;
|
||||
do {
|
||||
|
||||
@ -58,7 +59,8 @@ public final class ObjectMessageReader implements IMessageReader {
|
||||
}
|
||||
|
||||
// Get message length
|
||||
if (nextMessage.length < 4) return;
|
||||
if (nextMessage.length < 4)
|
||||
return;
|
||||
length = SerializationUtils.bytesToInt(nextMessage.sharedArray, nextMessage.offset) + 4;
|
||||
|
||||
} while (nextMessage.length >= length);
|
||||
|
@ -7,9 +7,10 @@ import java.util.stream.Stream;
|
||||
|
||||
import com.jenkov.nioserver.*;
|
||||
|
||||
import envoy.server.data.Contact;
|
||||
import envoy.util.*;
|
||||
|
||||
import envoy.server.data.Contact;
|
||||
|
||||
/**
|
||||
* This class defines methods to send an object to a client.
|
||||
*
|
||||
@ -21,7 +22,8 @@ public final class ObjectWriteProxy {
|
||||
private final WriteProxy writeProxy;
|
||||
|
||||
private static final ConnectionManager connectionManager = ConnectionManager.getInstance();
|
||||
private static final Logger logger = EnvoyLog.getLogger(ObjectWriteProxy.class);
|
||||
private static final Logger logger =
|
||||
EnvoyLog.getLogger(ObjectWriteProxy.class);
|
||||
|
||||
/**
|
||||
* Creates an instance of {@link ObjectWriteProxy}.
|
||||
@ -29,13 +31,14 @@ public final class ObjectWriteProxy {
|
||||
* @param writeProxy the {@link WriteProxy} to write objects to another client
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public ObjectWriteProxy(WriteProxy writeProxy) { this.writeProxy = writeProxy; }
|
||||
public ObjectWriteProxy(WriteProxy writeProxy) {
|
||||
this.writeProxy = writeProxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param recipientSocketID the socket id of the recipient
|
||||
* @param obj the object to return to the client
|
||||
* @throws RuntimeException if the serialization of the object failed (this is
|
||||
* highly unlikely)
|
||||
* @throws RuntimeException if the serialization of the object failed (this is highly unlikely)
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public void write(long recipientSocketID, Object obj) {
|
||||
@ -67,7 +70,9 @@ public final class ObjectWriteProxy {
|
||||
* @param message the object to send
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
public void writeToOnlineContacts(Set<? extends Contact> contacts, Object message) { writeToOnlineContacts(contacts.stream(), message); }
|
||||
public void writeToOnlineContacts(Set<? extends Contact> contacts, Object message) {
|
||||
writeToOnlineContacts(contacts.stream(), message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an object to all contacts in a set that are online.
|
||||
@ -77,6 +82,7 @@ public final class ObjectWriteProxy {
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
public void writeToOnlineContacts(Stream<? extends Contact> contacts, Object message) {
|
||||
contacts.map(Contact::getID).filter(connectionManager::isOnline).map(connectionManager::getSocketID).forEach(id -> write(id, message));
|
||||
contacts.map(Contact::getID).filter(connectionManager::isOnline)
|
||||
.map(connectionManager::getSocketID).forEach(id -> write(id, message));
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import static envoy.server.Startup.config;
|
||||
import java.util.HashSet;
|
||||
|
||||
import envoy.event.*;
|
||||
|
||||
import envoy.server.data.PersistenceManager;
|
||||
import envoy.server.net.*;
|
||||
|
||||
@ -32,7 +33,9 @@ public final class GroupCreationProcessor implements ObjectProcessor<GroupCreati
|
||||
.stream()
|
||||
.map(persistenceManager::getUserByID)
|
||||
.forEach(member -> persistenceManager.addContactBidirectional(member, group));
|
||||
persistenceManager.addContactBidirectional(persistenceManager.getUserByID(connectionManager.getUserIDBySocketID(socketID)), group);
|
||||
writeProxy.writeToOnlineContacts(group.getContacts(), new GroupCreationResult(group.toCommon()));
|
||||
persistenceManager.addContactBidirectional(
|
||||
persistenceManager.getUserByID(connectionManager.getUserIDBySocketID(socketID)), group);
|
||||
writeProxy.writeToOnlineContacts(group.getContacts(),
|
||||
new GroupCreationResult(group.toCommon()));
|
||||
}
|
||||
}
|
||||
|
@ -11,9 +11,10 @@ import javax.persistence.EntityExistsException;
|
||||
|
||||
import envoy.data.GroupMessage;
|
||||
import envoy.event.*;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import envoy.server.data.PersistenceManager;
|
||||
import envoy.server.net.*;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
/**
|
||||
* @author Maximilian Käfer
|
||||
@ -23,14 +24,16 @@ public final class GroupMessageProcessor implements ObjectProcessor<GroupMessage
|
||||
|
||||
private static final ConnectionManager connectionManager = ConnectionManager.getInstance();
|
||||
private static final PersistenceManager persistenceManager = PersistenceManager.getInstance();
|
||||
private static final Logger logger = EnvoyLog.getLogger(GroupCreationProcessor.class);
|
||||
private static final Logger logger =
|
||||
EnvoyLog.getLogger(GroupCreationProcessor.class);
|
||||
|
||||
@Override
|
||||
public void process(GroupMessage groupMessage, long socketID, ObjectWriteProxy writeProxy) {
|
||||
groupMessage.nextStatus();
|
||||
|
||||
// Update statuses to SENT / RECEIVED depending on online status
|
||||
groupMessage.getMemberStatuses().replaceAll((memberID, status) -> connectionManager.isOnline(memberID) ? RECEIVED : SENT);
|
||||
groupMessage.getMemberStatuses().replaceAll(
|
||||
(memberID, status) -> connectionManager.isOnline(memberID) ? RECEIVED : SENT);
|
||||
|
||||
// Set status for sender to READ
|
||||
groupMessage.getMemberStatuses().replace(groupMessage.getSenderID(), READ);
|
||||
@ -44,7 +47,8 @@ public final class GroupMessageProcessor implements ObjectProcessor<GroupMessage
|
||||
}
|
||||
|
||||
// message attachment will be automatically removed if disabled in config
|
||||
final var groupMessageServer = new envoy.server.data.GroupMessage(groupMessage, Instant.now());
|
||||
final var groupMessageServer =
|
||||
new envoy.server.data.GroupMessage(groupMessage, Instant.now());
|
||||
// Telling the server to reload the message without the attachment and telling
|
||||
// the client not to send anymore attachments
|
||||
if (!config.isAttachmentSupportEnabled() && groupMessage.hasAttachment()) {
|
||||
@ -57,11 +61,11 @@ public final class GroupMessageProcessor implements ObjectProcessor<GroupMessage
|
||||
final var groupMessageCopy = groupMessage;
|
||||
// Deliver the message to the recipients that are online
|
||||
writeProxy.writeToOnlineContacts(
|
||||
persistenceManager.getGroupByID(groupMessageCopy.getRecipientID())
|
||||
.getContacts()
|
||||
.stream()
|
||||
.filter(c -> c.getID() != groupMessageCopy.getSenderID()),
|
||||
groupMessageCopy);
|
||||
persistenceManager.getGroupByID(groupMessageCopy.getRecipientID())
|
||||
.getContacts()
|
||||
.stream()
|
||||
.filter(c -> c.getID() != groupMessageCopy.getSenderID()),
|
||||
groupMessageCopy);
|
||||
|
||||
try {
|
||||
PersistenceManager.getInstance().addMessage(groupMessageServer);
|
||||
|
@ -8,22 +8,26 @@ import java.util.logging.*;
|
||||
|
||||
import envoy.data.Message.MessageStatus;
|
||||
import envoy.event.*;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import envoy.server.data.*;
|
||||
import envoy.server.net.*;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
/**
|
||||
* @author Maximilian Käfer
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
public final class GroupMessageStatusChangeProcessor implements ObjectProcessor<GroupMessageStatusChange> {
|
||||
public final class GroupMessageStatusChangeProcessor
|
||||
implements ObjectProcessor<GroupMessageStatusChange> {
|
||||
|
||||
private static final ConnectionManager connectionManager = ConnectionManager.getInstance();
|
||||
private static final PersistenceManager persistenceManager = PersistenceManager.getInstance();
|
||||
private static final Logger logger = EnvoyLog.getLogger(MessageStatusChangeProcessor.class);
|
||||
private static final Logger logger =
|
||||
EnvoyLog.getLogger(MessageStatusChangeProcessor.class);
|
||||
|
||||
@Override
|
||||
public void process(GroupMessageStatusChange statusChange, long socketID, ObjectWriteProxy writeProxy) {
|
||||
public void process(GroupMessageStatusChange statusChange, long socketID,
|
||||
ObjectWriteProxy writeProxy) {
|
||||
GroupMessage gmsg = (GroupMessage) persistenceManager.getMessageByID(statusChange.getID());
|
||||
|
||||
// Any other status than READ is not supposed to be sent to the server
|
||||
@ -51,7 +55,7 @@ public final class GroupMessageStatusChangeProcessor implements ObjectProcessor<
|
||||
|
||||
// Notify online members about the status change
|
||||
writeProxy.writeToOnlineContacts(gmsg.getRecipient().getContacts(),
|
||||
new MessageStatusChange(gmsg.getID(), gmsg.getStatus(), Instant.now()));
|
||||
new MessageStatusChange(gmsg.getID(), gmsg.getStatus(), Instant.now()));
|
||||
}
|
||||
persistenceManager.updateMessage(gmsg);
|
||||
}
|
||||
|
@ -4,9 +4,10 @@ import java.time.Instant;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import envoy.event.GroupResize;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import envoy.server.data.*;
|
||||
import envoy.server.net.ObjectWriteProxy;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
/**
|
||||
* @author Maximilian Käfer
|
||||
@ -35,16 +36,19 @@ public final class GroupResizeProcessor implements ObjectProcessor<GroupResize>
|
||||
|
||||
// The group has no more members and hence will be deleted
|
||||
if (group.getContacts().isEmpty()) {
|
||||
EnvoyLog.getLogger(GroupResizeProcessor.class).log(Level.INFO, "Deleting now empty group " + group.getName());
|
||||
EnvoyLog.getLogger(GroupResizeProcessor.class).log(Level.INFO,
|
||||
"Deleting now empty group " + group.getName());
|
||||
persistenceManager.deleteContact(group);
|
||||
} else {
|
||||
|
||||
// Informing the other members
|
||||
writeProxy.writeToOnlineContacts(group.getContacts(), groupResize);
|
||||
group.getContacts().forEach(c -> ((User) c).setLatestContactDeletion(Instant.now()));
|
||||
group.getContacts()
|
||||
.forEach(c -> ((User) c).setLatestContactDeletion(Instant.now()));
|
||||
}
|
||||
|
||||
group.getContacts().remove(persistenceManager.getUserByID(groupResize.get().getID()));
|
||||
group.getContacts()
|
||||
.remove(persistenceManager.getUserByID(groupResize.get().getID()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import java.io.IOException;
|
||||
|
||||
import envoy.data.IDGenerator;
|
||||
import envoy.event.IDGeneratorRequest;
|
||||
|
||||
import envoy.server.data.*;
|
||||
import envoy.server.net.ObjectWriteProxy;
|
||||
|
||||
@ -17,7 +18,8 @@ public final class IDGeneratorRequestProcessor implements ObjectProcessor<IDGene
|
||||
private static final long ID_RANGE = 200;
|
||||
|
||||
@Override
|
||||
public void process(IDGeneratorRequest input, long socketID, ObjectWriteProxy writeProxy) throws IOException {
|
||||
public void process(IDGeneratorRequest input, long socketID, ObjectWriteProxy writeProxy)
|
||||
throws IOException {
|
||||
writeProxy.write(socketID, createIDGenerator());
|
||||
}
|
||||
|
||||
@ -25,7 +27,9 @@ public final class IDGeneratorRequestProcessor implements ObjectProcessor<IDGene
|
||||
* @return a new IDGenerator
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
public static IDGenerator createIDGenerator() { return createIDGenerator(ID_RANGE); }
|
||||
public static IDGenerator createIDGenerator() {
|
||||
return createIDGenerator(ID_RANGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param range of IDs used by the new IDGenerator
|
||||
@ -33,7 +37,8 @@ public final class IDGeneratorRequestProcessor implements ObjectProcessor<IDGene
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
public static IDGenerator createIDGenerator(long range) {
|
||||
ConfigItem currentID = PersistenceManager.getInstance().getConfigItemByID("currentMessageId");
|
||||
ConfigItem currentID =
|
||||
PersistenceManager.getInstance().getConfigItemByID("currentMessageId");
|
||||
IDGenerator generator = new IDGenerator(Integer.parseInt(currentID.getValue()), range);
|
||||
currentID.setValue(String.valueOf(Integer.parseInt(currentID.getValue()) + range));
|
||||
PersistenceManager.getInstance().updateConfigItem(currentID);
|
||||
|
@ -3,6 +3,7 @@ package envoy.server.processors;
|
||||
import java.io.IOException;
|
||||
|
||||
import envoy.event.IsTyping;
|
||||
|
||||
import envoy.server.data.*;
|
||||
import envoy.server.net.*;
|
||||
|
||||
@ -18,11 +19,14 @@ public final class IsTypingProcessor implements ObjectProcessor<IsTyping> {
|
||||
private static final PersistenceManager persistenceManager = PersistenceManager.getInstance();
|
||||
|
||||
@Override
|
||||
public void process(IsTyping event, long socketID, ObjectWriteProxy writeProxy) throws IOException {
|
||||
public void process(IsTyping event, long socketID, ObjectWriteProxy writeProxy)
|
||||
throws IOException {
|
||||
final var contact = persistenceManager.getContactByID(event.get());
|
||||
if (contact instanceof User) {
|
||||
final var destinationID = event.getDestinationID();
|
||||
if (connectionManager.isOnline(destinationID)) writeProxy.write(connectionManager.getSocketID(destinationID), event);
|
||||
} else writeProxy.writeToOnlineContacts(contact.getContacts(), event);
|
||||
if (connectionManager.isOnline(destinationID))
|
||||
writeProxy.write(connectionManager.getSocketID(destinationID), event);
|
||||
} else
|
||||
writeProxy.writeToOnlineContacts(contact.getContacts(), event);
|
||||
}
|
||||
}
|
||||
|
@ -7,12 +7,13 @@ import java.net.*;
|
||||
import java.util.logging.*;
|
||||
|
||||
import envoy.event.IssueProposal;
|
||||
import envoy.server.net.ObjectWriteProxy;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import envoy.server.net.ObjectWriteProxy;
|
||||
|
||||
/**
|
||||
* This processor handles incoming {@link IssueProposal}s and automatically
|
||||
* creates a new issue on the gitea site, if not disabled by its administrator.
|
||||
* This processor handles incoming {@link IssueProposal}s and automatically creates a new issue on
|
||||
* the gitea site, if not disabled by its administrator.
|
||||
*
|
||||
* @author Leon Hofmeister
|
||||
* @since Envoy Server v0.2-beta
|
||||
@ -22,9 +23,11 @@ public final class IssueProposalProcessor implements ObjectProcessor<IssuePropos
|
||||
private static final Logger logger = EnvoyLog.getLogger(IssueProposalProcessor.class);
|
||||
|
||||
@Override
|
||||
public void process(IssueProposal issueProposal, long socketID, ObjectWriteProxy writeProxy) throws IOException {
|
||||
public void process(IssueProposal issueProposal, long socketID, ObjectWriteProxy writeProxy)
|
||||
throws IOException {
|
||||
// Do nothing if manually disabled
|
||||
if (!config.isIssueReportingEnabled()) return;
|
||||
if (!config.isIssueReportingEnabled())
|
||||
return;
|
||||
try {
|
||||
final var url = new URL(config.getIssueReportingURL());
|
||||
final var connection = (HttpURLConnection) url.openConnection();
|
||||
@ -41,18 +44,22 @@ public final class IssueProposalProcessor implements ObjectProcessor<IssuePropos
|
||||
connection.setDoOutput(true);
|
||||
|
||||
final var json = String.format("{\"title\":\"%s\",\"body\":\"%s\",\"labels\":[%s, %s]}",
|
||||
issueProposal.get(),
|
||||
issueProposal.getDescription(),
|
||||
config.getUserMadeLabel(),
|
||||
issueProposal.isBug() ? config.getBugLabel() : config.getFeatureLabel());
|
||||
issueProposal.get(),
|
||||
issueProposal.getDescription(),
|
||||
config.getUserMadeLabel(),
|
||||
issueProposal.isBug() ? config.getBugLabel() : config.getFeatureLabel());
|
||||
try (final var os = connection.getOutputStream()) {
|
||||
final byte[] input = json.getBytes("utf-8");
|
||||
os.write(input, 0, input.length);
|
||||
}
|
||||
final var status = connection.getResponseCode();
|
||||
if (status == 201) logger.log(Level.INFO, "Successfully created an issue");
|
||||
else logger.log(Level.WARNING,
|
||||
String.format("Tried creating an issue for %s but received status code %d - Request params:%s", url, status, json));
|
||||
if (status == 201)
|
||||
logger.log(Level.INFO, "Successfully created an issue");
|
||||
else
|
||||
logger.log(Level.WARNING,
|
||||
String.format(
|
||||
"Tried creating an issue for %s but received status code %d - Request params:%s",
|
||||
url, status, json));
|
||||
} catch (final IOException e) {
|
||||
logger.log(Level.WARNING, "An error occurred while creating an issue: ", e);
|
||||
}
|
||||
|
@ -14,10 +14,11 @@ import javax.persistence.NoResultException;
|
||||
import envoy.data.LoginCredentials;
|
||||
import envoy.event.*;
|
||||
import envoy.event.contact.ContactsChangedSinceLastLogin;
|
||||
import envoy.util.*;
|
||||
|
||||
import envoy.server.data.*;
|
||||
import envoy.server.net.*;
|
||||
import envoy.server.util.*;
|
||||
import envoy.util.*;
|
||||
|
||||
/**
|
||||
* This {@link ObjectProcessor} handles {@link LoginCredentials}.
|
||||
@ -47,27 +48,29 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
|
||||
|
||||
// Acquire a user object (or reject the handshake if that's impossible)
|
||||
User user = null;
|
||||
if (!credentials.isRegistration()) try {
|
||||
user = persistenceManager.getUserByName(credentials.getIdentifier());
|
||||
if (!credentials.isRegistration())
|
||||
try {
|
||||
user = persistenceManager.getUserByName(credentials.getIdentifier());
|
||||
|
||||
// Check if the user is already online
|
||||
if (connectionManager.isOnline(user.getID())) {
|
||||
logger.warning(user + " is already online!");
|
||||
writeProxy.write(socketID, new HandshakeRejection(INTERNAL_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
// Authenticate with password or token
|
||||
if (credentials.usesToken()) {
|
||||
|
||||
// Check the token
|
||||
if (user.getAuthToken() == null || user.getAuthTokenExpiration().isBefore(Instant.now())
|
||||
|| !user.getAuthToken().equals(credentials.getPassword())) {
|
||||
logger.info(user + " tried to use an invalid token.");
|
||||
writeProxy.write(socketID, new HandshakeRejection(INVALID_TOKEN));
|
||||
// Check if the user is already online
|
||||
if (connectionManager.isOnline(user.getID())) {
|
||||
logger.warning(user + " is already online!");
|
||||
writeProxy.write(socketID, new HandshakeRejection(INTERNAL_ERROR));
|
||||
return;
|
||||
}
|
||||
} else
|
||||
|
||||
// Authenticate with password or token
|
||||
if (credentials.usesToken()) {
|
||||
|
||||
// Check the token
|
||||
if (user.getAuthToken() == null
|
||||
|| user.getAuthTokenExpiration().isBefore(Instant.now())
|
||||
|| !user.getAuthToken().equals(credentials.getPassword())) {
|
||||
logger.info(user + " tried to use an invalid token.");
|
||||
writeProxy.write(socketID, new HandshakeRejection(INVALID_TOKEN));
|
||||
return;
|
||||
}
|
||||
} else
|
||||
|
||||
// Check the password hash
|
||||
if (!PasswordUtil.validate(credentials.getPassword(), user.getPasswordHash())) {
|
||||
@ -75,11 +78,11 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
|
||||
writeProxy.write(socketID, new HandshakeRejection(WRONG_PASSWORD_OR_USER));
|
||||
return;
|
||||
}
|
||||
} catch (final NoResultException e) {
|
||||
logger.info("The requested user does not exist.");
|
||||
writeProxy.write(socketID, new HandshakeRejection(WRONG_PASSWORD_OR_USER));
|
||||
return;
|
||||
}
|
||||
} catch (final NoResultException e) {
|
||||
logger.info("The requested user does not exist.");
|
||||
writeProxy.write(socketID, new HandshakeRejection(WRONG_PASSWORD_OR_USER));
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
||||
// Validate user name
|
||||
@ -131,12 +134,14 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
|
||||
token = AuthTokenGenerator.nextToken();
|
||||
user.setAuthToken(token);
|
||||
}
|
||||
user.setAuthTokenExpiration(Instant.now().plus(ServerConfig.getInstance().getAuthTokenExpiration().longValue(), ChronoUnit.DAYS));
|
||||
user.setAuthTokenExpiration(Instant.now().plus(
|
||||
ServerConfig.getInstance().getAuthTokenExpiration().longValue(), ChronoUnit.DAYS));
|
||||
persistenceManager.updateContact(user);
|
||||
writeProxy.write(socketID, new NewAuthToken(token));
|
||||
}
|
||||
|
||||
final var pendingMessages = PersistenceManager.getInstance().getPendingMessages(user, credentials.getLastSync());
|
||||
final var pendingMessages =
|
||||
PersistenceManager.getInstance().getPendingMessages(user, credentials.getLastSync());
|
||||
pendingMessages.removeIf(GroupMessage.class::isInstance);
|
||||
logger.fine("Sending " + pendingMessages.size() + " pending messages to " + user + "...");
|
||||
|
||||
@ -156,19 +161,24 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
|
||||
// Notify the sender about the delivery
|
||||
if (connectionManager.isOnline(msg.getSender().getID())) {
|
||||
msgCommon.nextStatus();
|
||||
writeProxy.write(connectionManager.getSocketID(msg.getSender().getID()), new MessageStatusChange(msgCommon));
|
||||
writeProxy.write(connectionManager.getSocketID(msg.getSender().getID()),
|
||||
new MessageStatusChange(msgCommon));
|
||||
}
|
||||
} else writeProxy.write(socketID, new MessageStatusChange(msgCommon));
|
||||
} else
|
||||
writeProxy.write(socketID, new MessageStatusChange(msgCommon));
|
||||
}
|
||||
|
||||
final List<GroupMessage> pendingGroupMessages = PersistenceManager.getInstance().getPendingGroupMessages(user, credentials.getLastSync());
|
||||
logger.fine("Sending " + pendingGroupMessages.size() + " pending group messages to " + user + "...");
|
||||
final List<GroupMessage> pendingGroupMessages = PersistenceManager.getInstance()
|
||||
.getPendingGroupMessages(user, credentials.getLastSync());
|
||||
logger.fine("Sending " + pendingGroupMessages.size() + " pending group messages to " + user
|
||||
+ "...");
|
||||
|
||||
for (final var gmsg : pendingGroupMessages) {
|
||||
final var gmsgCommon = gmsg.toCommon();
|
||||
|
||||
// Deliver the message to the user if he hasn't received it yet
|
||||
if (gmsg.getCreationDate().isAfter(credentials.getLastSync()) || gmsg.getMemberMessageStatus().get(user.getID()) == SENT) {
|
||||
if (gmsg.getCreationDate().isAfter(credentials.getLastSync())
|
||||
|| gmsg.getMemberMessageStatus().get(user.getID()) == SENT) {
|
||||
if (gmsg.getMemberMessageStatus().replace(user.getID(), RECEIVED) != RECEIVED) {
|
||||
|
||||
gmsg.setLastStatusChangeDate(Instant.now());
|
||||
@ -177,14 +187,15 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
|
||||
|
||||
// Notify all online group members about the status change
|
||||
writeProxy.writeToOnlineContacts(gmsg.getRecipient().getContacts(),
|
||||
new GroupMessageStatusChange(gmsg.getID(), RECEIVED, Instant.now(), connectionManager.getUserIDBySocketID(socketID)));
|
||||
new GroupMessageStatusChange(gmsg.getID(), RECEIVED, Instant.now(),
|
||||
connectionManager.getUserIDBySocketID(socketID)));
|
||||
|
||||
if (Collections.min(gmsg.getMemberMessageStatus().values()) == RECEIVED) {
|
||||
gmsg.received();
|
||||
|
||||
// Notify online members about the status change
|
||||
writeProxy.writeToOnlineContacts(gmsg.getRecipient().getContacts(),
|
||||
new MessageStatusChange(gmsg.getID(), gmsg.getStatus(), Instant.now()));
|
||||
new MessageStatusChange(gmsg.getID(), gmsg.getStatus(), Instant.now()));
|
||||
}
|
||||
|
||||
PersistenceManager.getInstance().updateMessage(gmsg);
|
||||
@ -195,20 +206,25 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
|
||||
} else {
|
||||
|
||||
// Sending group message status changes
|
||||
if (gmsg.getStatus() == SENT && gmsg.getLastStatusChangeDate().isAfter(gmsg.getCreationDate())
|
||||
|| gmsg.getStatus() == RECEIVED && gmsg.getLastStatusChangeDate().isAfter(gmsg.getReceivedDate()))
|
||||
if (gmsg.getStatus() == SENT
|
||||
&& gmsg.getLastStatusChangeDate().isAfter(gmsg.getCreationDate())
|
||||
|| gmsg.getStatus() == RECEIVED
|
||||
&& gmsg.getLastStatusChangeDate().isAfter(gmsg.getReceivedDate()))
|
||||
gmsg.getMemberMessageStatus()
|
||||
.forEach((memberID, memberStatus) -> writeProxy.write(socketID,
|
||||
new GroupMessageStatusChange(gmsg.getID(), memberStatus, gmsg.getLastStatusChangeDate(), memberID)));
|
||||
new GroupMessageStatusChange(gmsg.getID(), memberStatus,
|
||||
gmsg.getLastStatusChangeDate(), memberID)));
|
||||
|
||||
// Deliver just a status change instead of the whole message
|
||||
if (gmsg.getStatus() == RECEIVED && user.getLastSeen().isBefore(gmsg.getReceivedDate())
|
||||
|| gmsg.getStatus() == READ && user.getLastSeen().isBefore(gmsg.getReadDate()))
|
||||
if (gmsg.getStatus() == RECEIVED
|
||||
&& user.getLastSeen().isBefore(gmsg.getReceivedDate())
|
||||
|| gmsg.getStatus() == READ && user.getLastSeen().isBefore(gmsg.getReadDate()))
|
||||
writeProxy.write(socketID, new MessageStatusChange(gmsgCommon));
|
||||
}
|
||||
}
|
||||
// Notify the user if a contact deletion has happened since he last logged in
|
||||
if (user.getLatestContactDeletion().isAfter(user.getLastSeen())) writeProxy.write(socketID, new ContactsChangedSinceLastLogin());
|
||||
if (user.getLatestContactDeletion().isAfter(user.getLastSeen()))
|
||||
writeProxy.write(socketID, new ContactsChangedSinceLastLogin());
|
||||
|
||||
// Complete the handshake
|
||||
writeProxy.write(socketID, user.toCommon());
|
||||
|
@ -8,9 +8,10 @@ import javax.persistence.EntityExistsException;
|
||||
|
||||
import envoy.data.Message;
|
||||
import envoy.event.*;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import envoy.server.data.PersistenceManager;
|
||||
import envoy.server.net.*;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
/**
|
||||
* This {@link ObjectProcessor} handles incoming {@link Message}s.
|
||||
@ -23,7 +24,8 @@ public final class MessageProcessor implements ObjectProcessor<Message> {
|
||||
|
||||
private static final PersistenceManager persistenceManager = PersistenceManager.getInstance();
|
||||
private static final ConnectionManager connectionManager = ConnectionManager.getInstance();
|
||||
private static final Logger logger = EnvoyLog.getLogger(MessageProcessor.class);
|
||||
private static final Logger logger =
|
||||
EnvoyLog.getLogger(MessageProcessor.class);
|
||||
|
||||
@Override
|
||||
public void process(Message message, long socketID, ObjectWriteProxy writeProxy) {
|
||||
|
@ -5,9 +5,10 @@ import java.util.logging.*;
|
||||
|
||||
import envoy.data.Message.MessageStatus;
|
||||
import envoy.event.MessageStatusChange;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import envoy.server.data.PersistenceManager;
|
||||
import envoy.server.net.*;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
/**
|
||||
* @author Leon Hofmeister
|
||||
@ -17,10 +18,12 @@ public final class MessageStatusChangeProcessor implements ObjectProcessor<Messa
|
||||
|
||||
private final ConnectionManager connectionManager = ConnectionManager.getInstance();
|
||||
private final PersistenceManager persistenceManager = PersistenceManager.getInstance();
|
||||
private final Logger logger = EnvoyLog.getLogger(MessageStatusChangeProcessor.class);
|
||||
private final Logger logger =
|
||||
EnvoyLog.getLogger(MessageStatusChangeProcessor.class);
|
||||
|
||||
@Override
|
||||
public void process(MessageStatusChange statusChange, long socketID, ObjectWriteProxy writeProxy) throws IOException {
|
||||
public void process(MessageStatusChange statusChange, long socketID,
|
||||
ObjectWriteProxy writeProxy) throws IOException {
|
||||
|
||||
// Any other status than READ is not supposed to be sent to the server
|
||||
if (statusChange.get() != MessageStatus.READ) {
|
||||
@ -34,6 +37,7 @@ public final class MessageStatusChangeProcessor implements ObjectProcessor<Messa
|
||||
|
||||
// Notifies the sender of the message about the status-update to READ
|
||||
final long senderID = msg.getSender().getID();
|
||||
if (connectionManager.isOnline(senderID)) writeProxy.write(connectionManager.getSocketID(senderID), statusChange);
|
||||
if (connectionManager.isOnline(senderID))
|
||||
writeProxy.write(connectionManager.getSocketID(senderID), statusChange);
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package envoy.server.processors;
|
||||
import java.io.IOException;
|
||||
|
||||
import envoy.event.NameChange;
|
||||
|
||||
import envoy.server.data.*;
|
||||
import envoy.server.net.ObjectWriteProxy;
|
||||
|
||||
@ -15,7 +16,8 @@ public final class NameChangeProcessor implements ObjectProcessor<NameChange> {
|
||||
private static final PersistenceManager persistenceManager = PersistenceManager.getInstance();
|
||||
|
||||
@Override
|
||||
public void process(NameChange nameChange, long socketID, ObjectWriteProxy writeProxy) throws IOException {
|
||||
public void process(NameChange nameChange, long socketID, ObjectWriteProxy writeProxy)
|
||||
throws IOException {
|
||||
Contact toUpdate = persistenceManager.getContactByID(nameChange.getID());
|
||||
toUpdate.setName(nameChange.get());
|
||||
persistenceManager.updateContact(toUpdate);
|
||||
|
@ -5,8 +5,7 @@ import java.io.IOException;
|
||||
import envoy.server.net.ObjectWriteProxy;
|
||||
|
||||
/**
|
||||
* This interface defines methods for processing objects of a specific
|
||||
* type incoming from a client.
|
||||
* This interface defines methods for processing objects of a specific type incoming from a client.
|
||||
*
|
||||
* @author Kai S. K. Engelbart
|
||||
* @param <T> type of the request object
|
||||
|
@ -4,27 +4,34 @@ import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import envoy.event.*;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import envoy.server.data.PersistenceManager;
|
||||
import envoy.server.net.ObjectWriteProxy;
|
||||
import envoy.server.util.PasswordUtil;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
/**
|
||||
* @author Leon Hofmeister
|
||||
* @since Envoy Server v0.2-beta
|
||||
*/
|
||||
public final class PasswordChangeRequestProcessor implements ObjectProcessor<PasswordChangeRequest> {
|
||||
public final class PasswordChangeRequestProcessor
|
||||
implements ObjectProcessor<PasswordChangeRequest> {
|
||||
|
||||
@Override
|
||||
public void process(PasswordChangeRequest event, long socketID, ObjectWriteProxy writeProxy) throws IOException {
|
||||
public void process(PasswordChangeRequest event, long socketID, ObjectWriteProxy writeProxy)
|
||||
throws IOException {
|
||||
final var persistenceManager = PersistenceManager.getInstance();
|
||||
final var user = persistenceManager.getUserByID(event.getID());
|
||||
final var logger = EnvoyLog.getLogger(PasswordChangeRequestProcessor.class);
|
||||
final var correctAuthentication = PasswordUtil.validate(event.getOldPassword(), user.getPasswordHash());
|
||||
final var logger =
|
||||
EnvoyLog.getLogger(PasswordChangeRequestProcessor.class);
|
||||
final var correctAuthentication =
|
||||
PasswordUtil.validate(event.getOldPassword(), user.getPasswordHash());
|
||||
if (correctAuthentication) {
|
||||
user.setPasswordHash(PasswordUtil.hash(event.get()));
|
||||
logger.log(Level.INFO, user + " changed his password");
|
||||
} else logger.log(Level.INFO, user + " tried changing his password but provided insufficient authentication");
|
||||
} else
|
||||
logger.log(Level.INFO,
|
||||
user + " tried changing his password but provided insufficient authentication");
|
||||
writeProxy.write(socketID, new PasswordChangeResult(correctAuthentication));
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package envoy.server.processors;
|
||||
import java.io.IOException;
|
||||
|
||||
import envoy.event.ProfilePicChange;
|
||||
|
||||
import envoy.server.net.ObjectWriteProxy;
|
||||
|
||||
/**
|
||||
@ -12,5 +13,6 @@ import envoy.server.net.ObjectWriteProxy;
|
||||
public final class ProfilePicChangeProcessor implements ObjectProcessor<ProfilePicChange> {
|
||||
|
||||
@Override
|
||||
public void process(ProfilePicChange event, long socketID, ObjectWriteProxy writeProxy) throws IOException {}
|
||||
public void process(ProfilePicChange event, long socketID, ObjectWriteProxy writeProxy)
|
||||
throws IOException {}
|
||||
}
|
||||
|
@ -5,9 +5,10 @@ import java.util.logging.*;
|
||||
|
||||
import envoy.event.ElementOperation;
|
||||
import envoy.event.contact.UserOperation;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import envoy.server.data.PersistenceManager;
|
||||
import envoy.server.net.*;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
/**
|
||||
* @author Kai S. K. Engelbart
|
||||
@ -16,7 +17,8 @@ import envoy.util.EnvoyLog;
|
||||
public final class UserOperationProcessor implements ObjectProcessor<UserOperation> {
|
||||
|
||||
private static final ConnectionManager connectionManager = ConnectionManager.getInstance();
|
||||
private static final Logger logger = EnvoyLog.getLogger(UserOperationProcessor.class);
|
||||
private static final Logger logger =
|
||||
EnvoyLog.getLogger(UserOperationProcessor.class);
|
||||
private static final PersistenceManager persistenceManager = PersistenceManager.getInstance();
|
||||
|
||||
@Override
|
||||
@ -26,12 +28,14 @@ public final class UserOperationProcessor implements ObjectProcessor<UserOperati
|
||||
final var sender = persistenceManager.getUserByID(userID);
|
||||
switch (evt.getOperationType()) {
|
||||
case ADD:
|
||||
logger.log(Level.FINE, String.format("Adding %s to the contact list of user %d.", evt.get(), userID));
|
||||
logger.log(Level.FINE,
|
||||
String.format("Adding %s to the contact list of user %d.", evt.get(), userID));
|
||||
persistenceManager.addContactBidirectional(userID, contactID);
|
||||
|
||||
// Notify the contact if online
|
||||
if (connectionManager.isOnline(contactID))
|
||||
writeProxy.write(connectionManager.getSocketID(contactID), new UserOperation(sender.toCommon(), ElementOperation.ADD));
|
||||
writeProxy.write(connectionManager.getSocketID(contactID),
|
||||
new UserOperation(sender.toCommon(), ElementOperation.ADD));
|
||||
break;
|
||||
case REMOVE:
|
||||
|
||||
@ -45,7 +49,8 @@ public final class UserOperationProcessor implements ObjectProcessor<UserOperati
|
||||
|
||||
// Notify the removed contact if online
|
||||
if (connectionManager.isOnline(contactID))
|
||||
writeProxy.write(connectionManager.getSocketID(contactID), new UserOperation(sender.toCommon(), ElementOperation.REMOVE));
|
||||
writeProxy.write(connectionManager.getSocketID(contactID),
|
||||
new UserOperation(sender.toCommon(), ElementOperation.REMOVE));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
import envoy.data.Contact;
|
||||
import envoy.event.contact.*;
|
||||
|
||||
import envoy.server.data.*;
|
||||
import envoy.server.net.*;
|
||||
|
||||
@ -16,19 +17,21 @@ import envoy.server.net.*;
|
||||
public final class UserSearchProcessor implements ObjectProcessor<UserSearchRequest> {
|
||||
|
||||
/**
|
||||
* Writes a list of contacts to the client containing all {@link Contact}s
|
||||
* matching the search phrase contained inside the request. The client and their
|
||||
* contacts are excluded from the result.
|
||||
* Writes a list of contacts to the client containing all {@link Contact}s matching the search
|
||||
* phrase contained inside the request. The client and their contacts are excluded from the
|
||||
* result.
|
||||
*
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
@Override
|
||||
public void process(UserSearchRequest request, long socketID, ObjectWriteProxy writeProxy) throws IOException {
|
||||
public void process(UserSearchRequest request, long socketID, ObjectWriteProxy writeProxy)
|
||||
throws IOException {
|
||||
writeProxy.write(socketID,
|
||||
new UserSearchResult(PersistenceManager.getInstance()
|
||||
.searchUsers(request.get(), ConnectionManager.getInstance().getUserIDBySocketID(socketID))
|
||||
.stream()
|
||||
.map(User::toCommon)
|
||||
.collect(Collectors.toList())));
|
||||
new UserSearchResult(PersistenceManager.getInstance()
|
||||
.searchUsers(request.get(),
|
||||
ConnectionManager.getInstance().getUserIDBySocketID(socketID))
|
||||
.stream()
|
||||
.map(User::toCommon)
|
||||
.collect(Collectors.toList())));
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,10 @@ import java.util.logging.Logger;
|
||||
|
||||
import envoy.data.User.UserStatus;
|
||||
import envoy.event.UserStatusChange;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import envoy.server.data.*;
|
||||
import envoy.server.net.ObjectWriteProxy;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
/**
|
||||
* This processor handles incoming {@link UserStatusChange}.
|
||||
@ -19,7 +20,8 @@ public final class UserStatusChangeProcessor implements ObjectProcessor<UserStat
|
||||
private static ObjectWriteProxy writeProxy;
|
||||
|
||||
private static final PersistenceManager persistenceManager = PersistenceManager.getInstance();
|
||||
private static final Logger logger = EnvoyLog.getLogger(UserStatusChangeProcessor.class);
|
||||
private static final Logger logger =
|
||||
EnvoyLog.getLogger(UserStatusChangeProcessor.class);
|
||||
|
||||
@Override
|
||||
public void process(UserStatusChange input, long socketID, ObjectWriteProxy writeProxy) {
|
||||
@ -32,8 +34,8 @@ public final class UserStatusChangeProcessor implements ObjectProcessor<UserStat
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link UserStatus} for a given user. Both offline contacts and
|
||||
* currently online contacts are notified.
|
||||
* Sets the {@link UserStatus} for a given user. Both offline contacts and currently online
|
||||
* contacts are notified.
|
||||
*
|
||||
* @param user the user whose status has changed
|
||||
* @param newStatus the new status of that user
|
||||
@ -47,19 +49,21 @@ public final class UserStatusChangeProcessor implements ObjectProcessor<UserStat
|
||||
persistenceManager.updateContact(user);
|
||||
|
||||
// Handling for contacts that are already online
|
||||
writeProxy.writeToOnlineContacts(user.getContacts(), new UserStatusChange(user.getID(), user.getStatus()));
|
||||
writeProxy.writeToOnlineContacts(user.getContacts(),
|
||||
new UserStatusChange(user.getID(), user.getStatus()));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only called by the LoginCredentialProcessor because every
|
||||
* user needs to login (open a socket) before changing his status.
|
||||
* Needed to ensure propagation of events because an uninitialized writeProxy
|
||||
* would cause problems.
|
||||
* This method is only called by the LoginCredentialProcessor because every user needs to login
|
||||
* (open a socket) before changing his status. Needed to ensure propagation of events because an
|
||||
* uninitialized writeProxy would cause problems.
|
||||
*
|
||||
* @param writeProxy the writeProxy that is used to send objects back to clients
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public static void setWriteProxy(ObjectWriteProxy writeProxy) { UserStatusChangeProcessor.writeProxy = writeProxy; }
|
||||
public static void setWriteProxy(ObjectWriteProxy writeProxy) {
|
||||
UserStatusChangeProcessor.writeProxy = writeProxy;
|
||||
}
|
||||
// TODO may cause an problem if two clients log in at the same time.
|
||||
// Change Needed.
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
/**
|
||||
* This package contains all classes that process data received from client
|
||||
* connections.
|
||||
* This package contains all classes that process data received from client connections.
|
||||
*
|
||||
* @author Kai S. K. Engelbart
|
||||
* @author Leon Hofmeister
|
||||
|
@ -11,7 +11,8 @@ import java.security.SecureRandom;
|
||||
public final class AuthTokenGenerator {
|
||||
|
||||
private static final int TOKEN_LENGTH = 128;
|
||||
private static final char[] CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
|
||||
private static final char[] CHARACTERS =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
|
||||
private static final char[] BUFF = new char[TOKEN_LENGTH];
|
||||
private static final SecureRandom RANDOM = new SecureRandom();
|
||||
|
||||
|
@ -7,9 +7,9 @@ import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
|
||||
/**
|
||||
* Provides a password hashing and comparison mechanism using the
|
||||
* {@code PBKDF2WithHmacSHA1} algorithm.
|
||||
*
|
||||
* Provides a password hashing and comparison mechanism using the {@code PBKDF2WithHmacSHA1}
|
||||
* algorithm.
|
||||
*
|
||||
* @author Kai S. K. Engelbart
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
@ -37,7 +37,8 @@ public final class PasswordUtil {
|
||||
byte[] salt = fromHex(parts[1]);
|
||||
byte[] hash = fromHex(parts[2]);
|
||||
|
||||
var spec = new PBEKeySpec(current.toCharArray(), salt, iterations, KEY_LENGTH);
|
||||
var spec =
|
||||
new PBEKeySpec(current.toCharArray(), salt, iterations, KEY_LENGTH);
|
||||
var skf = SecretKeyFactory.getInstance(SECRET_KEY_ALGORITHM);
|
||||
byte[] testHash = skf.generateSecret(spec).getEncoded();
|
||||
|
||||
@ -53,7 +54,7 @@ public final class PasswordUtil {
|
||||
|
||||
/**
|
||||
* Creates a parameterized salted password hash.
|
||||
*
|
||||
*
|
||||
* @param password the password to hash
|
||||
* @return a result string in the form of {@code iterations:salt:hash}
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
|
@ -3,8 +3,8 @@ package envoy.server.util;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Implements a comparison algorithm between Envoy versions and defines minimal
|
||||
* and maximal client versions compatible with this server.
|
||||
* Implements a comparison algorithm between Envoy versions and defines minimal and maximal client
|
||||
* versions compatible with this server.
|
||||
*
|
||||
* @author Kai S. K. Engelbart
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
@ -25,13 +25,14 @@ public final class VersionUtil {
|
||||
*/
|
||||
public static final String MAX_CLIENT_VERSION = "0.2-beta";
|
||||
|
||||
private static final Pattern versionPattern = Pattern.compile("(?<major>\\d).(?<minor>\\d)(?:-(?<suffix>\\w+))?");
|
||||
private static final Pattern versionPattern =
|
||||
Pattern.compile("(?<major>\\d).(?<minor>\\d)(?:-(?<suffix>\\w+))?");
|
||||
|
||||
private VersionUtil() {}
|
||||
|
||||
/**
|
||||
* Parses an Envoy Client version string and checks whether that version is
|
||||
* compatible with this server.
|
||||
* Parses an Envoy Client version string and checks whether that version is compatible with this
|
||||
* server.
|
||||
*
|
||||
* @param version the version string to parse
|
||||
* @return {@code true} if the given version is compatible with this server
|
||||
@ -40,12 +41,14 @@ public final class VersionUtil {
|
||||
public static boolean verifyCompatibility(String version) {
|
||||
final var currentMatcher = versionPattern.matcher(version);
|
||||
|
||||
if (!currentMatcher.matches()) return false;
|
||||
if (!currentMatcher.matches())
|
||||
return false;
|
||||
|
||||
final var minMatcher = versionPattern.matcher(MIN_CLIENT_VERSION);
|
||||
final var maxMatcher = versionPattern.matcher(MAX_CLIENT_VERSION);
|
||||
|
||||
if (!minMatcher.matches() || !maxMatcher.matches()) throw new RuntimeException("Invalid min or max client version configured!");
|
||||
if (!minMatcher.matches() || !maxMatcher.matches())
|
||||
throw new RuntimeException("Invalid min or max client version configured!");
|
||||
|
||||
// Compare suffixes
|
||||
{
|
||||
@ -53,7 +56,8 @@ public final class VersionUtil {
|
||||
final var minSuffix = convertSuffix(minMatcher.group("suffix"));
|
||||
final var maxSuffix = convertSuffix(maxMatcher.group("suffix"));
|
||||
|
||||
if (currentSuffix < minSuffix || currentSuffix > maxSuffix) return false;
|
||||
if (currentSuffix < minSuffix || currentSuffix > maxSuffix)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare major
|
||||
@ -62,7 +66,8 @@ public final class VersionUtil {
|
||||
final var minMajor = Integer.parseInt(minMatcher.group("major"));
|
||||
final var maxMajor = Integer.parseInt(maxMatcher.group("major"));
|
||||
|
||||
if (currentMajor < minMajor || currentMajor > maxMajor) return false;
|
||||
if (currentMajor < minMajor || currentMajor > maxMajor)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare minor
|
||||
@ -71,7 +76,8 @@ public final class VersionUtil {
|
||||
final var minMinor = Integer.parseInt(minMatcher.group("minor"));
|
||||
final var maxMinor = Integer.parseInt(maxMatcher.group("minor"));
|
||||
|
||||
if (currentMinor < minMinor || currentMinor > maxMinor) return false;
|
||||
if (currentMinor < minMinor || currentMinor > maxMinor)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* This package contains utility classes used in Envoy Server.
|
||||
*
|
||||
*
|
||||
* @author Kai S. K. Engelbart
|
||||
* @since Envoy Server Standalone v0.1-beta
|
||||
*/
|
||||
|
@ -1,6 +1,5 @@
|
||||
/**
|
||||
* This module contains all classes defining the server application of the Envoy
|
||||
* project.
|
||||
* This module contains all classes defining the server application of the Envoy project.
|
||||
*
|
||||
* @author Kai S. K. Engelbart
|
||||
* @author Leon Hofmeister
|
||||
|
Reference in New Issue
Block a user