/** * Copyright (c) 2016 Codetrails GmbH. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Johannes Dorn - initial API and implementation. */ package org.eclipse.recommenders.news.impl.read; import java.io.BufferedReader; import java.io.IOException; import java.io.Writer; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.Set; import java.util.concurrent.ConcurrentSkipListSet; import org.eclipse.core.runtime.Platform; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.recommenders.internal.news.impl.l10n.Messages; import org.eclipse.recommenders.news.api.NewsItem; import org.eclipse.recommenders.news.api.read.IReadItemsStore; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; import org.osgi.service.log.LogService; /** * File format modeled after <a href="https://www.iana.org/assignments/media-types/text/uri-list">text/uri-list</a>. */ public class DefaultReadItemsStore implements IReadItemsStore { private final Path fileLocation; private final Set<String> readIds; @Nullable private LogService logService; public DefaultReadItemsStore() { Bundle bundle = FrameworkUtil.getBundle(this.getClass()); Path stateLocation = Platform.getStateLocation(bundle).toFile().toPath(); fileLocation = stateLocation.resolve("read-items.uris"); //$NON-NLS-1$ readIds = intializeReadIds(); } private Set<String> intializeReadIds() { Set<String> readIds = new ConcurrentSkipListSet<>(); if (Files.exists(fileLocation)) { try (BufferedReader in = Files.newBufferedReader(fileLocation, StandardCharsets.UTF_8)) { String line; while ((line = in.readLine()) != null) { String id = line.substring(0, line.length()); readIds.add(id); } } catch (IOException e) { logError(Messages.LOG_ERROR_FAILED_TO_INITIALIZE_READ_ITEMS, e); } } return readIds; } @Override public void markAsRead(NewsItem feedItem) { String id = feedItem.getId(); if (readIds.add(id)) { synchronized (fileLocation) { try (Writer out = Files.newBufferedWriter(fileLocation, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND)) { out.append(id).append('\r').append('\n'); } catch (IOException e) { logError(Messages.LOG_ERROR_FAILED_TO_MARKED_AS_READ, e); } } } } @Override public boolean isRead(NewsItem feedItem) { return readIds.contains(feedItem.getId()); } public synchronized void bindLogService(LogService logService) { this.logService = logService; } public synchronized void unbindLogService(LogService logService) { if (this.logService == logService) { this.logService = null; } } private void logError(String message, Throwable e) { LogService localLogService = this.logService; if (localLogService != null) { localLogService.log(LogService.LOG_ERROR, message, e); } } }