blob: bb6eaf326d93d403d68cdb0c32c996cfc60491f6 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}