/* ********************************************************************** ** ** Copyright notice ** ** ** ** (c) 2005-2011 RSSOwl Development Team ** ** http://www.rssowl.org/ ** ** ** ** 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.rssowl.org/legal/epl-v10.html ** ** ** ** A copy is found in the file epl-v10.html and important notices to the ** ** license from the team is found in the textfile LICENSE.txt distributed ** ** in this package. ** ** ** ** This copyright notice MUST APPEAR in all copies of the file! ** ** ** ** Contributors: ** ** RSSOwl Development Team - initial API and implementation ** ** ** ** ********************************************************************** */ package org.rssowl.ui.internal.services; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.osgi.util.NLS; import org.rssowl.core.util.SyncItem; import org.rssowl.ui.internal.Activator; 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.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; /** * The {@link SyncItemsManager} serializes and deserializes uncommitted * {@link SyncItem} to the file system. * * @author bpasero */ public class SyncItemsManager { /* File of uncommitted sync items */ private static final String UNCOMMITTED_SYNCITEMS_FILE = "syncitems"; //$NON-NLS-1$ private Map<String, SyncItem> fItems = new HashMap<String, SyncItem>(); private final Object fLock = new Object(); /** * Deserialize Items from Filesystem * * @throws IOException * @throws ClassNotFoundException */ public void startup() throws IOException, ClassNotFoundException { synchronized (fLock) { fItems = deserializeSyncItems(); } } /** * Serialize Items to Filesystem * * @throws IOException */ public void shutdown() throws IOException { synchronized (fLock) { serializeSyncItems(fItems); fItems.clear(); } } /** * @param items the uncommitted {@link SyncItem} to add. */ public void addUncommitted(Collection<SyncItem> items) { synchronized (fLock) { for (SyncItem item : items) { SyncItem existingItem = fItems.get(item.getId()); if (existingItem != null) existingItem.merge(item); else fItems.put(item.getId(), item); } } } /** * @return all uncommitted {@link SyncItem}. */ public Map<String, SyncItem> getUncommittedItems() { synchronized (fLock) { if (fItems.isEmpty()) return Collections.emptyMap(); return new HashMap<String, SyncItem>(fItems); } } /** * @return <code>true</code> if there are uncommitted {@link SyncItem}. */ public boolean hasUncommittedItems() { synchronized (fLock) { return !fItems.isEmpty(); } } /** * Removes all uncommitted {@link SyncItem}. */ public void clearUncommittedItems() { synchronized (fLock) { fItems.clear(); } } /** * @param items the uncommitted {@link SyncItem} to remove. */ public void removeUncommitted(Collection<SyncItem> items) { synchronized (fLock) { for (SyncItem item : items) { fItems.remove(item.getId()); } } } /** * @param item the uncommitted {@link SyncItem} to remove. */ public void removeUncommitted(SyncItem item) { synchronized (fLock) { fItems.remove(item.getId()); } } private void serializeSyncItems(Map<String, SyncItem> items) throws IOException { File store = getUncommittedSyncItemsFile(); if (store == null) return; if (store.exists() && !store.delete()) throw new IOException(NLS.bind("Synchronization: Unable to delete file ''{0}''", store.toString())); //$NON-NLS-1$ if (fItems.isEmpty()) return; ObjectOutputStream outS = null; try { outS = new ObjectOutputStream(new FileOutputStream(store)); outS.writeObject(items); } finally { if (outS != null) outS.close(); } } @SuppressWarnings("unchecked") private Map<String, SyncItem> deserializeSyncItems() throws IOException, ClassNotFoundException { Map<String, SyncItem> items = new HashMap<String, SyncItem>(); File store = getUncommittedSyncItemsFile(); if (store == null || !store.exists()) return items; ObjectInputStream inS = null; try { inS = new ObjectInputStream(new FileInputStream(store)); Object obj = inS.readObject(); if (obj instanceof Map) items.putAll((Map) obj); } finally { if (inS != null) inS.close(); } return items; } private File getUncommittedSyncItemsFile() throws IOException { Activator activator = Activator.getDefault(); if (activator == null) return null; IPath path = new Path(activator.getStateLocation().toOSString()); File bundleRoot = new File(path.toOSString()); if (!bundleRoot.exists() && !bundleRoot.mkdir()) throw new IOException(NLS.bind("Synchronization: Unable to create folder ''{0}''", bundleRoot.toString())); //$NON-NLS-1$ path = path.append(UNCOMMITTED_SYNCITEMS_FILE); return new File(path.toOSString()); } }