package envoy.data; import java.io.*; import java.util.*; /** * Represents a unique user with a unique, numeric ID, a name and a current {@link UserStatus}.
* * @author Kai S. K. Engelbart * @since Envoy Common v0.2-alpha */ public final class User extends Contact { private UserStatus status; /** * Used to serialize contact list to a maximum depth of one. */ private transient boolean serializeContacts = true; private static final long serialVersionUID = 1L; /** * This enumeration defines all possible statuses a user can have. * * @since Envoy Common v0.2-alpha */ public enum UserStatus { /** * select this, if a user is online and can be interacted with */ ONLINE, /** * select this, if a user is online but unavailable at the moment (sudden interruption) */ AWAY, /** * select this, if a user is online but unavailable at the moment (polite way) */ BUSY, /** * select this, if a user is offline */ OFFLINE; } /** * Initializes a {@link User}.
* The {@link UserStatus} is set to {@link UserStatus#ONLINE}. No contacts are initialized. * * @param id unique ID * @param name user name * @since Envoy Common v0.2-alpha */ public User(long id, String name) { super(id, name, new HashSet<>()); status = UserStatus.ONLINE; } /** * Initializes a {@link User}.
* The {@link UserStatus} is set to {@link UserStatus#ONLINE}. * * @param id unique ID * @param name user name * @param contacts the contacts of this user * @since Envoy Common v0.2-alpha */ public User(long id, String name, Set contacts) { super(id, name, contacts); status = UserStatus.ONLINE; } /** * Initializes a {@link User}. * * @param id unique ID * @param name user name * @param status the status of this user * @param contacts the contacts of this user * @since Envoy Common v0.2-alpha */ public User(long id, String name, UserStatus status, Set contacts) { super(id, name, contacts); this.status = status; } @Override public String toString() { return String.format("User[id=%d,name=%s,status=%s", id, name, status) + (contacts.isEmpty() ? "]" : "," + contacts.size() + " contact(s)]"); } /** * @return the current status of this user * @since Envoy Common v0.2-alpha */ public UserStatus getStatus() { return status; } /** * @param status the next status of this user * @since Envoy Common v0.2-alpha */ public void setStatus(UserStatus status) { this.status = status; } private void readObject(ObjectInputStream inputStream) throws Exception { inputStream.defaultReadObject(); var contacts = Contact.class.getDeclaredField("contacts"); contacts.setAccessible(true); contacts.set(this, inputStream.readObject()); } private void writeObject(ObjectOutputStream outputStream) throws Exception { outputStream.defaultWriteObject(); if (serializeContacts) { getContacts().stream().filter(User.class::isInstance).map(User.class::cast) .forEach(user -> user.serializeContacts = false); outputStream.writeObject(getContacts()); } else outputStream.writeObject(new HashSet<>()); } /** * @param serializeContacts whether the contacts of this {@link User} should be serialized * @since Envoy Common v0.1-beta */ public void serializeContacts(boolean serializeContacts) { this.serializeContacts = serializeContacts; } }