| 
							
							
							
						 |  |  | @@ -1,303 +1,303 @@ | 
		
	
		
			
				|  |  |  |  | package envoy.client; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | import java.io.File; | 
		
	
		
			
				|  |  |  |  | import java.io.FileInputStream; | 
		
	
		
			
				|  |  |  |  | import java.io.FileOutputStream; | 
		
	
		
			
				|  |  |  |  | import java.io.IOException; | 
		
	
		
			
				|  |  |  |  | import java.io.ObjectInputStream; | 
		
	
		
			
				|  |  |  |  | import java.io.ObjectOutputStream; | 
		
	
		
			
				|  |  |  |  | import java.time.Instant; | 
		
	
		
			
				|  |  |  |  | import java.util.ArrayList; | 
		
	
		
			
				|  |  |  |  | import java.util.List; | 
		
	
		
			
				|  |  |  |  | import java.util.logging.Logger; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | import javax.xml.datatype.DatatypeConfigurationException; | 
		
	
		
			
				|  |  |  |  | import javax.xml.datatype.DatatypeFactory; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | import envoy.client.event.EventBus; | 
		
	
		
			
				|  |  |  |  | import envoy.client.event.MessageCreationEvent; | 
		
	
		
			
				|  |  |  |  | import envoy.exception.EnvoyException; | 
		
	
		
			
				|  |  |  |  | import envoy.schema.Message; | 
		
	
		
			
				|  |  |  |  | import envoy.schema.Message.Metadata.MessageState; | 
		
	
		
			
				|  |  |  |  | import envoy.schema.ObjectFactory; | 
		
	
		
			
				|  |  |  |  | import envoy.schema.Sync; | 
		
	
		
			
				|  |  |  |  | import envoy.schema.User; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /** | 
		
	
		
			
				|  |  |  |  |  * Project: <strong>envoy-client</strong><br> | 
		
	
		
			
				|  |  |  |  |  * File: <strong>LocalDB.java</strong><br> | 
		
	
		
			
				|  |  |  |  |  * Created: <strong>27.10.2019</strong><br> | 
		
	
		
			
				|  |  |  |  |  * | 
		
	
		
			
				|  |  |  |  |  * @author Kai S. K. Engelbart | 
		
	
		
			
				|  |  |  |  |  * @author Maximilian Käfer | 
		
	
		
			
				|  |  |  |  |  * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
		
			
				|  |  |  |  | public class LocalDB { | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	private File			localDB; | 
		
	
		
			
				|  |  |  |  | 	private User			sender; | 
		
	
		
			
				|  |  |  |  | 	private List<Chat>		chats			= new ArrayList<>(); | 
		
	
		
			
				|  |  |  |  | 	private ObjectFactory	objectFactory	= new ObjectFactory(); | 
		
	
		
			
				|  |  |  |  | 	private DatatypeFactory	datatypeFactory; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	private Sync	unreadMessagesSync	= objectFactory.createSync(); | 
		
	
		
			
				|  |  |  |  | 	private Sync	sync				= objectFactory.createSync(); | 
		
	
		
			
				|  |  |  |  | 	private Sync	readMessages		= objectFactory.createSync(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	private static final Logger logger = Logger.getLogger(LocalDB.class.getSimpleName()); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Constructs an empty local database. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @param client the user that is logged in with this client | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public LocalDB(User sender) { | 
		
	
		
			
				|  |  |  |  | 		this.sender = sender; | 
		
	
		
			
				|  |  |  |  | 		try { | 
		
	
		
			
				|  |  |  |  | 			datatypeFactory = DatatypeFactory.newInstance(); | 
		
	
		
			
				|  |  |  |  | 		} catch (DatatypeConfigurationException e) { | 
		
	
		
			
				|  |  |  |  | 			e.printStackTrace(); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Initializes the local database and fills it with values | 
		
	
		
			
				|  |  |  |  | 	 * if the user has already sent or received messages. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @param localDBDir the directory where we wish to save/load the database from. | 
		
	
		
			
				|  |  |  |  | 	 * @throws EnvoyException if the directory selected is not an actual directory. | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public void initializeDBFile(File localDBDir) throws EnvoyException { | 
		
	
		
			
				|  |  |  |  | 		if (localDBDir.exists() && !localDBDir.isDirectory()) | 
		
	
		
			
				|  |  |  |  | 			throw new EnvoyException(String.format("LocalDBDir '%s' is not a directory!", localDBDir.getAbsolutePath())); | 
		
	
		
			
				|  |  |  |  | 		localDB = new File(localDBDir, sender.getID() + ".db"); | 
		
	
		
			
				|  |  |  |  | 		if (localDB.exists()) loadFromLocalDB(); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Saves the database into a file for future use. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @throws IOException if something went wrong during saving | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public void saveToLocalDB() { | 
		
	
		
			
				|  |  |  |  | 		try { | 
		
	
		
			
				|  |  |  |  | 			localDB.getParentFile().mkdirs(); | 
		
	
		
			
				|  |  |  |  | 			localDB.createNewFile(); | 
		
	
		
			
				|  |  |  |  | 		} catch (IOException e) { | 
		
	
		
			
				|  |  |  |  | 			e.printStackTrace(); | 
		
	
		
			
				|  |  |  |  | 			logger.warning("unable to save the messages"); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(localDB))) { | 
		
	
		
			
				|  |  |  |  | 			out.writeObject(chats); | 
		
	
		
			
				|  |  |  |  | 		} catch (IOException ex) { | 
		
	
		
			
				|  |  |  |  | 			ex.printStackTrace(); | 
		
	
		
			
				|  |  |  |  | 			logger.warning("unable to save the messages"); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Loads all chats saved by Envoy for the client user. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @throws EnvoyException if something fails while loading. | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	@SuppressWarnings("unchecked") | 
		
	
		
			
				|  |  |  |  | 	private void loadFromLocalDB() throws EnvoyException { | 
		
	
		
			
				|  |  |  |  | 		try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(localDB))) { | 
		
	
		
			
				|  |  |  |  | 			Object obj = in.readObject(); | 
		
	
		
			
				|  |  |  |  | 			if (obj instanceof ArrayList<?>) chats = (ArrayList<Chat>) obj; | 
		
	
		
			
				|  |  |  |  | 		} catch (ClassNotFoundException | IOException e) { | 
		
	
		
			
				|  |  |  |  | 			throw new EnvoyException(e); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Creates a {@link Message} object serializable to XML. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @param textContent The content (text) of the message | 
		
	
		
			
				|  |  |  |  | 	 * @return prepared {@link Message} object | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public Message createMessage(String textContent, User recipient) { | 
		
	
		
			
				|  |  |  |  | 		Message.Metadata metaData = objectFactory.createMessageMetadata(); | 
		
	
		
			
				|  |  |  |  | 		metaData.setSender(sender.getID()); | 
		
	
		
			
				|  |  |  |  | 		metaData.setRecipient(recipient.getID()); | 
		
	
		
			
				|  |  |  |  | 		metaData.setState(MessageState.WAITING); | 
		
	
		
			
				|  |  |  |  | 		metaData.setDate(datatypeFactory.newXMLGregorianCalendar(Instant.now().toString())); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		Message.Content content = objectFactory.createMessageContent(); | 
		
	
		
			
				|  |  |  |  | 		content.setType("text"); | 
		
	
		
			
				|  |  |  |  | 		content.setText(textContent); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		Message message = objectFactory.createMessage(); | 
		
	
		
			
				|  |  |  |  | 		message.setMetadata(metaData); | 
		
	
		
			
				|  |  |  |  | 		message.getContent().add(content); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		return message; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	public Sync fillSync(long userId) { | 
		
	
		
			
				|  |  |  |  | 		addWaitingMessagesToSync(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		sync.getMessages().addAll(readMessages.getMessages()); | 
		
	
		
			
				|  |  |  |  | 		readMessages.getMessages().clear(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		logger.info(String.format("Filled sync with %d messages.", sync.getMessages().size())); | 
		
	
		
			
				|  |  |  |  | 		return sync; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	public void applySync(Sync returnSync) { | 
		
	
		
			
				|  |  |  |  | 		for (int i = 0; i < returnSync.getMessages().size(); i++) { | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 			// The message has an ID | 
		
	
		
			
				|  |  |  |  | 			if (returnSync.getMessages().get(i).getMetadata().getMessageId() != 0) { | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 				// Messages are processes differently corresponding to their state | 
		
	
		
			
				|  |  |  |  | 				switch (returnSync.getMessages().get(i).getMetadata().getState()) { | 
		
	
		
			
				|  |  |  |  | 					case SENT: | 
		
	
		
			
				|  |  |  |  | 						// Update previously waiting and now sent messages that were assigned an ID by | 
		
	
		
			
				|  |  |  |  | 						// the server | 
		
	
		
			
				|  |  |  |  | 						sync.getMessages().get(i).getMetadata().setMessageId(returnSync.getMessages().get(i).getMetadata().getMessageId()); | 
		
	
		
			
				|  |  |  |  | 						sync.getMessages().get(i).getMetadata().setState(returnSync.getMessages().get(i).getMetadata().getState()); | 
		
	
		
			
				|  |  |  |  | 						break; | 
		
	
		
			
				|  |  |  |  | 					case RECEIVED: | 
		
	
		
			
				|  |  |  |  | 						if (returnSync.getMessages().get(i).getMetadata().getSender() != 0) { | 
		
	
		
			
				|  |  |  |  | 							// these are the unread Messages from the server | 
		
	
		
			
				|  |  |  |  | 							unreadMessagesSync.getMessages().add(returnSync.getMessages().get(i)); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 							// Create and dispatch message creation event | 
		
	
		
			
				|  |  |  |  | 							EventBus.getInstance().dispatch(new MessageCreationEvent(returnSync.getMessages().get(i))); | 
		
	
		
			
				|  |  |  |  | 						} else { | 
		
	
		
			
				|  |  |  |  | 							// Update Messages in localDB to state RECEIVED | 
		
	
		
			
				|  |  |  |  | 							for (int j = 0; j < getChats().size(); j++) { | 
		
	
		
			
				|  |  |  |  | 								if (getChats().get(j).getRecipient().getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) { | 
		
	
		
			
				|  |  |  |  | 									for (int k = 0; k < getChats().get(j).getModel().getSize(); k++) { | 
		
	
		
			
				|  |  |  |  | 										if (getChats().get(j).getModel().get(k).getMetadata().getMessageId() == returnSync.getMessages() | 
		
	
		
			
				|  |  |  |  | 											.get(i) | 
		
	
		
			
				|  |  |  |  | 											.getMetadata() | 
		
	
		
			
				|  |  |  |  | 											.getMessageId()) { | 
		
	
		
			
				|  |  |  |  | 											// Update Message in LocalDB | 
		
	
		
			
				|  |  |  |  | 											getChats().get(j) | 
		
	
		
			
				|  |  |  |  | 												.getModel() | 
		
	
		
			
				|  |  |  |  | 												.get(k) | 
		
	
		
			
				|  |  |  |  | 												.getMetadata() | 
		
	
		
			
				|  |  |  |  | 												.setState(returnSync.getMessages().get(j).getMetadata().getState()); | 
		
	
		
			
				|  |  |  |  | 										} | 
		
	
		
			
				|  |  |  |  | 									} | 
		
	
		
			
				|  |  |  |  | 								} | 
		
	
		
			
				|  |  |  |  | 							} | 
		
	
		
			
				|  |  |  |  | 						} | 
		
	
		
			
				|  |  |  |  | 						break; | 
		
	
		
			
				|  |  |  |  | 					case READ: | 
		
	
		
			
				|  |  |  |  | 						// Update local Messages to state READ | 
		
	
		
			
				|  |  |  |  | 						logger.info("Message with ID: " + returnSync.getMessages().get(i).getMetadata().getMessageId() | 
		
	
		
			
				|  |  |  |  | 								+ "was initialized to be set to READ in localDB."); | 
		
	
		
			
				|  |  |  |  | 						for (int j = 0; j < getChats().size(); j++) { | 
		
	
		
			
				|  |  |  |  | 							if (getChats().get(j).getRecipient().getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) { | 
		
	
		
			
				|  |  |  |  | 								logger.info("Chat with: " + getChats().get(j).getRecipient().getID() + "was selected."); | 
		
	
		
			
				|  |  |  |  | 								for (int k = 0; k < getChats().get(j).getModel().getSize(); k++) { | 
		
	
		
			
				|  |  |  |  | 									if (getChats().get(j).getModel().get(k).getMetadata().getMessageId() == returnSync.getMessages() | 
		
	
		
			
				|  |  |  |  | 										.get(i) | 
		
	
		
			
				|  |  |  |  | 										.getMetadata() | 
		
	
		
			
				|  |  |  |  | 										.getMessageId()) { | 
		
	
		
			
				|  |  |  |  | 										logger.info("Message with ID: " + getChats().get(j).getModel().get(k).getMetadata().getMessageId() | 
		
	
		
			
				|  |  |  |  | 												+ "was selected."); | 
		
	
		
			
				|  |  |  |  | 										getChats().get(j) | 
		
	
		
			
				|  |  |  |  | 											.getModel() | 
		
	
		
			
				|  |  |  |  | 											.get(k) | 
		
	
		
			
				|  |  |  |  | 											.getMetadata() | 
		
	
		
			
				|  |  |  |  | 											.setState(returnSync.getMessages().get(i).getMetadata().getState()); | 
		
	
		
			
				|  |  |  |  | 										logger.info( | 
		
	
		
			
				|  |  |  |  | 												"Message State is now: " + getChats().get(j).getModel().get(k).getMetadata().getState().toString()); | 
		
	
		
			
				|  |  |  |  | 									} | 
		
	
		
			
				|  |  |  |  | 								} | 
		
	
		
			
				|  |  |  |  | 							} | 
		
	
		
			
				|  |  |  |  | 						} | 
		
	
		
			
				|  |  |  |  | 						break; | 
		
	
		
			
				|  |  |  |  | 				} | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		// Updating UserStatus of all users in LocalDB | 
		
	
		
			
				|  |  |  |  | 		for (User user : returnSync.getUsers()) | 
		
	
		
			
				|  |  |  |  | 			for (Chat chat : getChats()) | 
		
	
		
			
				|  |  |  |  | 				if (user.getID() == chat.getRecipient().getID()) { | 
		
	
		
			
				|  |  |  |  | 					chat.getRecipient().setStatus(user.getStatus()); | 
		
	
		
			
				|  |  |  |  | 					logger.info(chat.getRecipient().getStatus().toString()); | 
		
	
		
			
				|  |  |  |  | 				} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		sync.getMessages().clear(); | 
		
	
		
			
				|  |  |  |  | 		sync.getUsers().clear(); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Adds the unread messages returned from the server in the latest sync to the | 
		
	
		
			
				|  |  |  |  | 	 * right chats in the LocalDB. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @param localDB | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public void addUnreadMessagesToLocalDB() { | 
		
	
		
			
				|  |  |  |  | 		for(Message message : unreadMessagesSync.getMessages()) | 
		
	
		
			
				|  |  |  |  | 			for(Chat chat : getChats()) | 
		
	
		
			
				|  |  |  |  | 				if(message.getMetadata().getSender() == chat.getRecipient().getID()) { | 
		
	
		
			
				|  |  |  |  | 					chat.appendMessage(message); | 
		
	
		
			
				|  |  |  |  | 					break; | 
		
	
		
			
				|  |  |  |  | 				} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Changes all messages with state {@code RECEIVED} of a specific chat to state | 
		
	
		
			
				|  |  |  |  | 	 * {@code READ}. | 
		
	
		
			
				|  |  |  |  | 	 * <br> | 
		
	
		
			
				|  |  |  |  | 	 * Adds these messages to the {@code readMessages} {@link Sync} object. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @param currentChat | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public void setMessagesToRead(Chat currentChat) { | 
		
	
		
			
				|  |  |  |  | 		for (int i = currentChat.getModel().size() - 1; i >= 0; --i) | 
		
	
		
			
				|  |  |  |  | 			if (currentChat.getModel().get(i).getMetadata().getRecipient() != currentChat.getRecipient().getID()) | 
		
	
		
			
				|  |  |  |  | 				if (currentChat.getModel().get(i).getMetadata().getState() == MessageState.RECEIVED) { | 
		
	
		
			
				|  |  |  |  | 					currentChat.getModel().get(i).getMetadata().setState(MessageState.READ); | 
		
	
		
			
				|  |  |  |  | 					readMessages.getMessages().add(currentChat.getModel().get(i)); | 
		
	
		
			
				|  |  |  |  | 				} else break; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Adds all messages with state {@code WAITING} from the {@link LocalDB} to the | 
		
	
		
			
				|  |  |  |  | 	 * {@link Sync} object. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	private void addWaitingMessagesToSync() { | 
		
	
		
			
				|  |  |  |  | 		for (Chat chat : getChats()) | 
		
	
		
			
				|  |  |  |  | 			for (int i = 0; i < chat.getModel().size(); i++) | 
		
	
		
			
				|  |  |  |  | 				if (chat.getModel().get(i).getMetadata().getState() == MessageState.WAITING) { | 
		
	
		
			
				|  |  |  |  | 					logger.info("Got Waiting Message"); | 
		
	
		
			
				|  |  |  |  | 					sync.getMessages().add(chat.getModel().get(i)); | 
		
	
		
			
				|  |  |  |  | 				} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Clears the {@code unreadMessagesSync} {@link Sync} object. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public void clearUnreadMessagesSync() { unreadMessagesSync.getMessages().clear(); } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * @return all saved {@link Chat} objects that list the client user as the | 
		
	
		
			
				|  |  |  |  | 	 *         sender | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 **/ | 
		
	
		
			
				|  |  |  |  | 	public List<Chat> getChats() { return chats; } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * @return the {@link User} who initialized the local database | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public User getUser() { return sender; } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | package envoy.client; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | import java.io.File; | 
		
	
		
			
				|  |  |  |  | import java.io.FileInputStream; | 
		
	
		
			
				|  |  |  |  | import java.io.FileOutputStream; | 
		
	
		
			
				|  |  |  |  | import java.io.IOException; | 
		
	
		
			
				|  |  |  |  | import java.io.ObjectInputStream; | 
		
	
		
			
				|  |  |  |  | import java.io.ObjectOutputStream; | 
		
	
		
			
				|  |  |  |  | import java.time.Instant; | 
		
	
		
			
				|  |  |  |  | import java.util.ArrayList; | 
		
	
		
			
				|  |  |  |  | import java.util.List; | 
		
	
		
			
				|  |  |  |  | import java.util.logging.Logger; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | import javax.xml.datatype.DatatypeConfigurationException; | 
		
	
		
			
				|  |  |  |  | import javax.xml.datatype.DatatypeFactory; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | import envoy.client.event.EventBus; | 
		
	
		
			
				|  |  |  |  | import envoy.client.event.MessageCreationEvent; | 
		
	
		
			
				|  |  |  |  | import envoy.exception.EnvoyException; | 
		
	
		
			
				|  |  |  |  | import envoy.schema.Message; | 
		
	
		
			
				|  |  |  |  | import envoy.schema.Message.Metadata.MessageState; | 
		
	
		
			
				|  |  |  |  | import envoy.schema.ObjectFactory; | 
		
	
		
			
				|  |  |  |  | import envoy.schema.Sync; | 
		
	
		
			
				|  |  |  |  | import envoy.schema.User; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /** | 
		
	
		
			
				|  |  |  |  |  * Project: <strong>envoy-client</strong><br> | 
		
	
		
			
				|  |  |  |  |  * File: <strong>LocalDB.java</strong><br> | 
		
	
		
			
				|  |  |  |  |  * Created: <strong>27.10.2019</strong><br> | 
		
	
		
			
				|  |  |  |  |  * | 
		
	
		
			
				|  |  |  |  |  * @author Kai S. K. Engelbart | 
		
	
		
			
				|  |  |  |  |  * @author Maximilian Käfer | 
		
	
		
			
				|  |  |  |  |  * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
		
			
				|  |  |  |  | public class LocalDB { | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	private File			localDB; | 
		
	
		
			
				|  |  |  |  | 	private User			sender; | 
		
	
		
			
				|  |  |  |  | 	private List<Chat>		chats			= new ArrayList<>(); | 
		
	
		
			
				|  |  |  |  | 	private ObjectFactory	objectFactory	= new ObjectFactory(); | 
		
	
		
			
				|  |  |  |  | 	private DatatypeFactory	datatypeFactory; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	private Sync	unreadMessagesSync	= objectFactory.createSync(); | 
		
	
		
			
				|  |  |  |  | 	private Sync	sync				= objectFactory.createSync(); | 
		
	
		
			
				|  |  |  |  | 	private Sync	readMessages		= objectFactory.createSync(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	private static final Logger logger = Logger.getLogger(LocalDB.class.getSimpleName()); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Constructs an empty local database. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @param client the user that is logged in with this client | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public LocalDB(User sender) { | 
		
	
		
			
				|  |  |  |  | 		this.sender = sender; | 
		
	
		
			
				|  |  |  |  | 		try { | 
		
	
		
			
				|  |  |  |  | 			datatypeFactory = DatatypeFactory.newInstance(); | 
		
	
		
			
				|  |  |  |  | 		} catch (DatatypeConfigurationException e) { | 
		
	
		
			
				|  |  |  |  | 			e.printStackTrace(); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Initializes the local database and fills it with values | 
		
	
		
			
				|  |  |  |  | 	 * if the user has already sent or received messages. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @param localDBDir the directory where we wish to save/load the database from. | 
		
	
		
			
				|  |  |  |  | 	 * @throws EnvoyException if the directory selected is not an actual directory. | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public void initializeDBFile(File localDBDir) throws EnvoyException { | 
		
	
		
			
				|  |  |  |  | 		if (localDBDir.exists() && !localDBDir.isDirectory()) | 
		
	
		
			
				|  |  |  |  | 			throw new EnvoyException(String.format("LocalDBDir '%s' is not a directory!", localDBDir.getAbsolutePath())); | 
		
	
		
			
				|  |  |  |  | 		localDB = new File(localDBDir, sender.getID() + ".db"); | 
		
	
		
			
				|  |  |  |  | 		if (localDB.exists()) loadFromLocalDB(); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Saves the database into a file for future use. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @throws IOException if something went wrong during saving | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public void saveToLocalDB() { | 
		
	
		
			
				|  |  |  |  | 		try { | 
		
	
		
			
				|  |  |  |  | 			localDB.getParentFile().mkdirs(); | 
		
	
		
			
				|  |  |  |  | 			localDB.createNewFile(); | 
		
	
		
			
				|  |  |  |  | 		} catch (IOException e) { | 
		
	
		
			
				|  |  |  |  | 			e.printStackTrace(); | 
		
	
		
			
				|  |  |  |  | 			logger.warning("unable to save the messages"); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(localDB))) { | 
		
	
		
			
				|  |  |  |  | 			out.writeObject(chats); | 
		
	
		
			
				|  |  |  |  | 		} catch (IOException ex) { | 
		
	
		
			
				|  |  |  |  | 			ex.printStackTrace(); | 
		
	
		
			
				|  |  |  |  | 			logger.warning("unable to save the messages"); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Loads all chats saved by Envoy for the client user. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @throws EnvoyException if something fails while loading. | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	@SuppressWarnings("unchecked") | 
		
	
		
			
				|  |  |  |  | 	private void loadFromLocalDB() throws EnvoyException { | 
		
	
		
			
				|  |  |  |  | 		try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(localDB))) { | 
		
	
		
			
				|  |  |  |  | 			Object obj = in.readObject(); | 
		
	
		
			
				|  |  |  |  | 			if (obj instanceof ArrayList<?>) chats = (ArrayList<Chat>) obj; | 
		
	
		
			
				|  |  |  |  | 		} catch (ClassNotFoundException | IOException e) { | 
		
	
		
			
				|  |  |  |  | 			throw new EnvoyException(e); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Creates a {@link Message} object serializable to XML. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @param textContent The content (text) of the message | 
		
	
		
			
				|  |  |  |  | 	 * @return prepared {@link Message} object | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public Message createMessage(String textContent, User recipient) { | 
		
	
		
			
				|  |  |  |  | 		Message.Metadata metaData = objectFactory.createMessageMetadata(); | 
		
	
		
			
				|  |  |  |  | 		metaData.setSender(sender.getID()); | 
		
	
		
			
				|  |  |  |  | 		metaData.setRecipient(recipient.getID()); | 
		
	
		
			
				|  |  |  |  | 		metaData.setState(MessageState.WAITING); | 
		
	
		
			
				|  |  |  |  | 		metaData.setDate(datatypeFactory.newXMLGregorianCalendar(Instant.now().toString())); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		Message.Content content = objectFactory.createMessageContent(); | 
		
	
		
			
				|  |  |  |  | 		content.setType("text"); | 
		
	
		
			
				|  |  |  |  | 		content.setText(textContent); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		Message message = objectFactory.createMessage(); | 
		
	
		
			
				|  |  |  |  | 		message.setMetadata(metaData); | 
		
	
		
			
				|  |  |  |  | 		message.getContent().add(content); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		return message; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	public Sync fillSync(long userId) { | 
		
	
		
			
				|  |  |  |  | 		addWaitingMessagesToSync(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		sync.getMessages().addAll(readMessages.getMessages()); | 
		
	
		
			
				|  |  |  |  | 		readMessages.getMessages().clear(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		logger.info(String.format("Filled sync with %d messages.", sync.getMessages().size())); | 
		
	
		
			
				|  |  |  |  | 		return sync; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	public void applySync(Sync returnSync) { | 
		
	
		
			
				|  |  |  |  | 		for (int i = 0; i < returnSync.getMessages().size(); i++) { | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 			// The message has an ID | 
		
	
		
			
				|  |  |  |  | 			if (returnSync.getMessages().get(i).getMetadata().getMessageId() != 0) { | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 				// Messages are processes differently corresponding to their state | 
		
	
		
			
				|  |  |  |  | 				switch (returnSync.getMessages().get(i).getMetadata().getState()) { | 
		
	
		
			
				|  |  |  |  | 					case SENT: | 
		
	
		
			
				|  |  |  |  | 						// Update previously waiting and now sent messages that were assigned an ID by | 
		
	
		
			
				|  |  |  |  | 						// the server | 
		
	
		
			
				|  |  |  |  | 						sync.getMessages().get(i).getMetadata().setMessageId(returnSync.getMessages().get(i).getMetadata().getMessageId()); | 
		
	
		
			
				|  |  |  |  | 						sync.getMessages().get(i).getMetadata().setState(returnSync.getMessages().get(i).getMetadata().getState()); | 
		
	
		
			
				|  |  |  |  | 						break; | 
		
	
		
			
				|  |  |  |  | 					case RECEIVED: | 
		
	
		
			
				|  |  |  |  | 						if (returnSync.getMessages().get(i).getMetadata().getSender() != 0) { | 
		
	
		
			
				|  |  |  |  | 							// these are the unread Messages from the server | 
		
	
		
			
				|  |  |  |  | 							unreadMessagesSync.getMessages().add(returnSync.getMessages().get(i)); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 							// Create and dispatch message creation event | 
		
	
		
			
				|  |  |  |  | 							EventBus.getInstance().dispatch(new MessageCreationEvent(returnSync.getMessages().get(i))); | 
		
	
		
			
				|  |  |  |  | 						} else { | 
		
	
		
			
				|  |  |  |  | 							// Update Messages in localDB to state RECEIVED | 
		
	
		
			
				|  |  |  |  | 							for (int j = 0; j < getChats().size(); j++) { | 
		
	
		
			
				|  |  |  |  | 								if (getChats().get(j).getRecipient().getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) { | 
		
	
		
			
				|  |  |  |  | 									for (int k = 0; k < getChats().get(j).getModel().getSize(); k++) { | 
		
	
		
			
				|  |  |  |  | 										if (getChats().get(j).getModel().get(k).getMetadata().getMessageId() == returnSync.getMessages() | 
		
	
		
			
				|  |  |  |  | 											.get(i) | 
		
	
		
			
				|  |  |  |  | 											.getMetadata() | 
		
	
		
			
				|  |  |  |  | 											.getMessageId()) { | 
		
	
		
			
				|  |  |  |  | 											// Update Message in LocalDB | 
		
	
		
			
				|  |  |  |  | 											getChats().get(j) | 
		
	
		
			
				|  |  |  |  | 												.getModel() | 
		
	
		
			
				|  |  |  |  | 												.get(k) | 
		
	
		
			
				|  |  |  |  | 												.getMetadata() | 
		
	
		
			
				|  |  |  |  | 												.setState(returnSync.getMessages().get(j).getMetadata().getState()); | 
		
	
		
			
				|  |  |  |  | 										} | 
		
	
		
			
				|  |  |  |  | 									} | 
		
	
		
			
				|  |  |  |  | 								} | 
		
	
		
			
				|  |  |  |  | 							} | 
		
	
		
			
				|  |  |  |  | 						} | 
		
	
		
			
				|  |  |  |  | 						break; | 
		
	
		
			
				|  |  |  |  | 					case READ: | 
		
	
		
			
				|  |  |  |  | 						// Update local Messages to state READ | 
		
	
		
			
				|  |  |  |  | 						logger.info("Message with ID: " + returnSync.getMessages().get(i).getMetadata().getMessageId() | 
		
	
		
			
				|  |  |  |  | 								+ "was initialized to be set to READ in localDB."); | 
		
	
		
			
				|  |  |  |  | 						for (int j = 0; j < getChats().size(); j++) { | 
		
	
		
			
				|  |  |  |  | 							if (getChats().get(j).getRecipient().getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) { | 
		
	
		
			
				|  |  |  |  | 								logger.info("Chat with: " + getChats().get(j).getRecipient().getID() + "was selected."); | 
		
	
		
			
				|  |  |  |  | 								for (int k = 0; k < getChats().get(j).getModel().getSize(); k++) { | 
		
	
		
			
				|  |  |  |  | 									if (getChats().get(j).getModel().get(k).getMetadata().getMessageId() == returnSync.getMessages() | 
		
	
		
			
				|  |  |  |  | 										.get(i) | 
		
	
		
			
				|  |  |  |  | 										.getMetadata() | 
		
	
		
			
				|  |  |  |  | 										.getMessageId()) { | 
		
	
		
			
				|  |  |  |  | 										logger.info("Message with ID: " + getChats().get(j).getModel().get(k).getMetadata().getMessageId() | 
		
	
		
			
				|  |  |  |  | 												+ "was selected."); | 
		
	
		
			
				|  |  |  |  | 										getChats().get(j) | 
		
	
		
			
				|  |  |  |  | 											.getModel() | 
		
	
		
			
				|  |  |  |  | 											.get(k) | 
		
	
		
			
				|  |  |  |  | 											.getMetadata() | 
		
	
		
			
				|  |  |  |  | 											.setState(returnSync.getMessages().get(i).getMetadata().getState()); | 
		
	
		
			
				|  |  |  |  | 										logger.info( | 
		
	
		
			
				|  |  |  |  | 												"Message State is now: " + getChats().get(j).getModel().get(k).getMetadata().getState().toString()); | 
		
	
		
			
				|  |  |  |  | 									} | 
		
	
		
			
				|  |  |  |  | 								} | 
		
	
		
			
				|  |  |  |  | 							} | 
		
	
		
			
				|  |  |  |  | 						} | 
		
	
		
			
				|  |  |  |  | 						break; | 
		
	
		
			
				|  |  |  |  | 				} | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		// Updating UserStatus of all users in LocalDB | 
		
	
		
			
				|  |  |  |  | 		for (User user : returnSync.getUsers()) | 
		
	
		
			
				|  |  |  |  | 			for (Chat chat : getChats()) | 
		
	
		
			
				|  |  |  |  | 				if (user.getID() == chat.getRecipient().getID()) { | 
		
	
		
			
				|  |  |  |  | 					chat.getRecipient().setStatus(user.getStatus()); | 
		
	
		
			
				|  |  |  |  | 					logger.info(chat.getRecipient().getStatus().toString()); | 
		
	
		
			
				|  |  |  |  | 				} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		sync.getMessages().clear(); | 
		
	
		
			
				|  |  |  |  | 		sync.getUsers().clear(); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Adds the unread messages returned from the server in the latest sync to the | 
		
	
		
			
				|  |  |  |  | 	 * right chats in the LocalDB. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @param localDB | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public void addUnreadMessagesToLocalDB() { | 
		
	
		
			
				|  |  |  |  | 		for(Message message : unreadMessagesSync.getMessages()) | 
		
	
		
			
				|  |  |  |  | 			for(Chat chat : getChats()) | 
		
	
		
			
				|  |  |  |  | 				if(message.getMetadata().getSender() == chat.getRecipient().getID()) { | 
		
	
		
			
				|  |  |  |  | 					chat.appendMessage(message); | 
		
	
		
			
				|  |  |  |  | 					break; | 
		
	
		
			
				|  |  |  |  | 				} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Changes all messages with state {@code RECEIVED} of a specific chat to state | 
		
	
		
			
				|  |  |  |  | 	 * {@code READ}. | 
		
	
		
			
				|  |  |  |  | 	 * <br> | 
		
	
		
			
				|  |  |  |  | 	 * Adds these messages to the {@code readMessages} {@link Sync} object. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @param currentChat | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public void setMessagesToRead(Chat currentChat) { | 
		
	
		
			
				|  |  |  |  | 		for (int i = currentChat.getModel().size() - 1; i >= 0; --i) | 
		
	
		
			
				|  |  |  |  | 			if (currentChat.getModel().get(i).getMetadata().getRecipient() != currentChat.getRecipient().getID()) | 
		
	
		
			
				|  |  |  |  | 				if (currentChat.getModel().get(i).getMetadata().getState() == MessageState.RECEIVED) { | 
		
	
		
			
				|  |  |  |  | 					currentChat.getModel().get(i).getMetadata().setState(MessageState.READ); | 
		
	
		
			
				|  |  |  |  | 					readMessages.getMessages().add(currentChat.getModel().get(i)); | 
		
	
		
			
				|  |  |  |  | 				} else break; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Adds all messages with state {@code WAITING} from the {@link LocalDB} to the | 
		
	
		
			
				|  |  |  |  | 	 * {@link Sync} object. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	private void addWaitingMessagesToSync() { | 
		
	
		
			
				|  |  |  |  | 		for (Chat chat : getChats()) | 
		
	
		
			
				|  |  |  |  | 			for (int i = 0; i < chat.getModel().size(); i++) | 
		
	
		
			
				|  |  |  |  | 				if (chat.getModel().get(i).getMetadata().getState() == MessageState.WAITING) { | 
		
	
		
			
				|  |  |  |  | 					logger.info("Got Waiting Message"); | 
		
	
		
			
				|  |  |  |  | 					sync.getMessages().add(chat.getModel().get(i)); | 
		
	
		
			
				|  |  |  |  | 				} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * Clears the {@code unreadMessagesSync} {@link Sync} object. | 
		
	
		
			
				|  |  |  |  | 	 * | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public void clearUnreadMessagesSync() { unreadMessagesSync.getMessages().clear(); } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * @return all saved {@link Chat} objects that list the client user as the | 
		
	
		
			
				|  |  |  |  | 	 *         sender | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 **/ | 
		
	
		
			
				|  |  |  |  | 	public List<Chat> getChats() { return chats; } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
		
			
				|  |  |  |  | 	 * @return the {@link User} who initialized the local database | 
		
	
		
			
				|  |  |  |  | 	 * @since Envoy v0.1-alpha | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public User getUser() { return sender; } | 
		
	
		
			
				|  |  |  |  | } |