/** * Registers a local file to be observed for changes. * * @param localPath Absolute path in the local file system to the file to be observed. * @param account OwnCloud account associated to the local file. */ private void addObservedFile(String localPath, Account account) { File file = new File(localPath); String parentPath = file.getParent(); FolderObserver observer = mFolderObserversMap.get(parentPath); if (observer == null) { observer = new FolderObserver(parentPath, account, getApplicationContext()); mFolderObserversMap.put(parentPath, observer); Log_OC.d(TAG, "Observer added for parent folder " + parentPath + "/"); } observer.startWatching(file.getName()); Log_OC.d(TAG, "Added " + localPath + " to list of observed children"); }
/** * Unregisters a local file from being observed for changes. * * @param localPath Absolute path in the local file system to the target file. */ private void removeObservedFile(String localPath) { File file = new File(localPath); String parentPath = file.getParent(); FolderObserver observer = mFolderObserversMap.get(parentPath); if (observer != null) { observer.stopWatching(file.getName()); if (observer.isEmpty()) { mFolderObserversMap.remove(parentPath); Log_OC.d(TAG, "Observer removed for parent folder " + parentPath + "/"); } } else { Log_OC.d(TAG, "No observer to remove for path " + localPath); } }
@Override public void onReceive(Context context, Intent intent) { Log_OC.d(TAG, "Received broadcast intent " + intent); File downloadedFile = new File(intent.getStringExtra(FileDownloader.EXTRA_FILE_PATH)); String parentPath = downloadedFile.getParent(); FolderObserver observer = mFolderObserversMap.get(parentPath); if (observer != null) { if (intent.getAction().equals(FileDownloader.getDownloadFinishMessage()) && downloadedFile.exists()) { // no matter if the download was successful or not; the // file could be down anyway due to a former download or upload observer.startWatching(downloadedFile.getName()); Log_OC.d(TAG, "Resuming observance of " + downloadedFile.getAbsolutePath()); } else if (intent.getAction().equals(FileDownloader.getDownloadAddedMessage())) { observer.stopWatching(downloadedFile.getName()); Log_OC.d(TAG, "Pausing observance of " + downloadedFile.getAbsolutePath()); } } else { Log_OC.d(TAG, "No observer for path " + downloadedFile.getAbsolutePath()); } }
private void processMessage(String message) throws Exception { Boolean toStdOut = logAllMessagesForUsers.get(config.getUsername()); if (toStdOut != null) { if (toStdOut) System.out.println("IMAPrcv[" + config.getUsername() + "]: " + message); else log.info("IMAPrcv[{}]: {}", config.getUsername(), message); } wireTrace.add(message); log.trace(message); if (SYSTEM_ERROR_REGEX.matcher(message).matches() || ". NO [ALERT] Account exceeded command or bandwidth limits. (Failure)" .equalsIgnoreCase(message.trim())) { log.warn( "{} disconnected by IMAP Server due to system error: {}", config.getUsername(), message); disconnectAbnormally(message); return; } try { if (halt) { log.error( "Mail client for {} is halted but continues to receive messages, ignoring!", config.getUsername()); return; } if (loginSuccess.getCount() > 0) { if (message.startsWith(CAPABILITY_PREFIX)) { this.capabilities = Arrays.asList(message.substring(CAPABILITY_PREFIX.length() + 1).split("[ ]+")); return; } else if (AUTH_SUCCESS_REGEX.matcher(message).matches()) { log.info("Authentication success for user {}", config.getUsername()); loginSuccess.countDown(); } else { Matcher matcher = COMMAND_FAILED_REGEX.matcher(message); if (matcher.find()) { // WARNING: DO NOT COUNTDOWN THE LOGIN LATCH ON FAILURE!!! log.warn("Authentication failed for {} due to: {}", config.getUsername(), message); errorStack.push( new Error( null /* logins have no completion */, extractError(matcher), wireTrace.list())); disconnectAbnormally(message); } } return; } // Copy to local var as the value can change underneath us. FolderObserver observer = this.observer; if (idleRequested.get() || idleAcknowledged.get()) { synchronized (idleMutex) { if (IDLE_ENDED_REGEX.matcher(message).matches()) { idleRequested.compareAndSet(true, false); idleAcknowledged.set(false); // Now fire the events. PushedData data = pushedData; pushedData = null; idler.idleEnd(); observer.changed( data.pushAdds.isEmpty() ? null : data.pushAdds, data.pushRemoves.isEmpty() ? null : data.pushRemoves); return; } // Queue up any push notifications to publish to the client in a second. Matcher existsMatcher = IDLE_EXISTS_REGEX.matcher(message); boolean matched = false; if (existsMatcher.matches()) { int number = Integer.parseInt(existsMatcher.group(1)); pushedData.pushAdds.add(number); pushedData.pushRemoves.remove(number); matched = true; } else { Matcher expungeMatcher = IDLE_EXPUNGE_REGEX.matcher(message); if (expungeMatcher.matches()) { int number = Integer.parseInt(expungeMatcher.group(1)); pushedData.pushRemoves.add(number); pushedData.pushAdds.remove(number); matched = true; } } // Stop idling, when we get the idle ended message (next cycle) we can publish what's been // gathered. if (matched) { if (!pushedData.idleExitSent) { idler.done(); pushedData.idleExitSent = true; } return; } } } complete(message); } catch (Exception ex) { CommandCompletion completion = completions.poll(); if (completion != null) completion.error(message, ex); else { log.error( "Strange exception during mail processing (no completions available!): {}", message, ex); errorStack.push(new Error(null, "No completions available!", wireTrace.list())); } throw ex; } }