| /******************************************************************************* |
| * Copyright (c) 2011, 2015 Wind River Systems, Inc. and others. 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: |
| * William Chen (Wind River) [360494]Provide an "Open With" action in the pop |
| * up menu of file system nodes of Target Explorer. |
| *******************************************************************************/ |
| package org.eclipse.tcf.te.tcf.filesystem.core.internal.utils; |
| |
| import java.io.File; |
| import java.net.URI; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.eclipse.core.runtime.ISafeRunnable; |
| import org.eclipse.core.runtime.QualifiedName; |
| import org.eclipse.core.runtime.SafeRunner; |
| import org.eclipse.core.runtime.content.IContentType; |
| import org.eclipse.tcf.te.runtime.persistence.interfaces.IURIPersistenceService; |
| import org.eclipse.tcf.te.runtime.services.ServiceManager; |
| import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.runtime.IFSTreeNode; |
| import org.eclipse.tcf.te.tcf.filesystem.core.internal.FSTreeNode; |
| |
| /** |
| * A facility class to load and save persistent data such including resolved content types, file's |
| * properties, and time stamps etc. |
| */ |
| public class PersistenceManager { |
| // The singleton instance. |
| private static volatile PersistenceManager instance; |
| |
| // The time stamp for each file. |
| Map<URI, FileState> digests; |
| |
| // Already known resolved content type of file nodes specified by their URIs. |
| Map<URI, IContentType> resolved; |
| |
| // Already known unresolvable file nodes specified by their URIs. |
| Map<URI, URI> unresolved; |
| |
| // The persistent properties of the files. |
| Map<URI, Map<QualifiedName, String>> properties; |
| |
| // The file used to store persistent properties of each file. |
| private static final String PERSISTENT_FILE = "persistent.ini"; //$NON-NLS-1$ |
| |
| /** |
| * Get the singleton cache manager. |
| * |
| * @return The singleton cache manager. |
| */ |
| public static PersistenceManager getInstance() { |
| if (instance == null) { |
| instance = new PersistenceManager(); |
| } |
| return instance; |
| } |
| |
| /** |
| * Create a Persistent Manager instance. |
| */ |
| private PersistenceManager() { |
| digests = new HashMap<URI, FileState>(); |
| resolved = new HashMap<URI, IContentType>(); |
| unresolved = new HashMap<URI, URI>(); |
| properties = new HashMap<URI, Map<QualifiedName, String>>(); |
| SafeRunner.run(new ISafeRunnable(){ |
| @Override |
| public void handleException(Throwable exception) { |
| // Ignore on purpose |
| } |
| @Override |
| public void run() throws Exception { |
| IURIPersistenceService service = ServiceManager.getInstance().getService(IURIPersistenceService.class); |
| File location = CacheManager.getCacheRoot(); |
| File persistentFile = new File(location, PERSISTENT_FILE); |
| if (persistentFile.exists()) { |
| service.read(PersistenceManager.this, persistentFile.getAbsoluteFile().toURI()); |
| } |
| }}); |
| } |
| |
| /** |
| * If the node is already considered unresolvable. |
| * |
| * @param node The file node. |
| * @return true if it is not resolvable or else false. |
| */ |
| public boolean isUnresovled(FSTreeNode node) { |
| return unresolved.get(node.getLocationURI()) != null; |
| } |
| |
| /** |
| * Get the resolved content type of the node. |
| * |
| * @param node The file node. |
| * @return the content type of the node if it is resolvable or null. |
| */ |
| public IContentType getResolved(FSTreeNode node) { |
| return resolved.get(node.getLocationURI()); |
| } |
| |
| /** |
| * Add the node and its content type to the resolved list. |
| * |
| * @param node The file node. |
| * @param contentType Its content type. |
| */ |
| public void addResovled(FSTreeNode node, IContentType contentType) { |
| resolved.put(node.getLocationURI(), contentType); |
| } |
| |
| /** |
| * Add the node as an unresolvable node. |
| * |
| * @param node The file node. |
| */ |
| public void addUnresolved(FSTreeNode node) { |
| unresolved.put(node.getLocationURI(), node.getLocationURI()); |
| } |
| |
| /** |
| * Set the time stamp of the FSTreeNode with the specified location. |
| * |
| * @param uri The FSTreeNode's location URI. |
| * @param digest The new base time stamp to be set. |
| */ |
| public void setFileDigest(URI uri, FileState digest) { |
| digests.put(uri, digest); |
| } |
| |
| /** |
| * Remove the time stamp entry with the specified URI. |
| * |
| * @param uri The URI key. |
| */ |
| public void removeFileDigest(URI uri) { |
| digests.remove(uri); |
| } |
| |
| /** |
| * Get the time stamp of the FSTreeNode with the specified location. |
| * |
| * @return The FSTreeNode's base time stamp. |
| */ |
| public FileState getFileDigest(FSTreeNode node) { |
| URI uri = node.getLocationURI(); |
| FileState digest = digests.get(uri); |
| if(digest == null) { |
| digest = new FileState(node); |
| digests.put(uri, digest); |
| } |
| digest.setNode(node); |
| return digest; |
| } |
| |
| /** |
| * Get the file properties of the specified node from the properties map. |
| * |
| * @param node The file node. |
| * @return The file properties object or empty properties object if it does not exist. |
| */ |
| public Map<QualifiedName, String> getPersistentProperties(IFSTreeNode node) { |
| Map<QualifiedName, String> nodeProperties = properties.get(node.getLocationURI()); |
| if (nodeProperties == null) { |
| nodeProperties = Collections.synchronizedMap(new HashMap<QualifiedName, String>()); |
| properties.put(node.getLocationURI(), nodeProperties); |
| } |
| return nodeProperties; |
| } |
| |
| /** |
| * Dispose the cache manager so that it has a chance to save the digests and the persistent |
| * properties. |
| */ |
| public void dispose() { |
| SafeRunner.run(new ISafeRunnable(){ |
| @Override |
| public void handleException(Throwable exception) { |
| // Ignore on purpose. |
| } |
| @Override |
| public void run() throws Exception { |
| IURIPersistenceService service = ServiceManager.getInstance().getService(IURIPersistenceService.class); |
| File location = CacheManager.getCacheRoot(); |
| File persistentFile = new File(location, PERSISTENT_FILE); |
| service.write(PersistenceManager.this, persistentFile.getAbsoluteFile().toURI()); |
| }}); |
| } |
| |
| /** |
| * Returns if or if not the persistence manager needs to be disposed. |
| * |
| * @return <code>True</code> if the persistence manager needs disposal, <code>false</code> otherwise. |
| */ |
| public final static boolean needsDisposal() { |
| return instance != null; |
| } |
| } |