blob: 81aabca94cb0e3219d46af5cb4ce00c97363f3cb [file] [log] [blame]
package org.eclipse.team.core.internal;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IPath;
import org.eclipse.team.core.IFileTypeRegistry;
import org.eclipse.team.core.TeamPlugin;
/**
* This class is the temporary home of functionality to determine
* whether a particular IResource should be treated as ASCII or Binary.
*/
public class FileTypeRegistry implements IFileTypeRegistry {
// Constant for the saved state file name
private static final String STATE_FILE = ".fileTypeState";
// The registry hash table
private Hashtable registry;
/**
* Create a new FileTypeRegistry.
*/
public FileTypeRegistry() {
this.registry = new Hashtable(11);
}
/**
* Initialize the registry, restoring its state
*/
public void startup() {
loadPluginState();
}
/**
* Shut down the registry, persisting its state
*/
public void shutdown() {
savePluginState();
}
/**
* @see IFileTypeRegistry#getValue(String, String)
*/
public String getValue(String extension, String key) {
Hashtable keyTable = (Hashtable)registry.get(extension);
if (keyTable == null) return null;
return (String)keyTable.get(key);
}
/**
* @see IFileTypeRegistry#getExtensions
*/
public String[] getExtensions(String key) {
String[] result = new String[registry.size()];
registry.keySet().toArray(result);
return result;
}
/**
* @see IFileTypeRegistry#setValue
*/
public void setValue(String extension, String key, String value) {
Hashtable keyTable = (Hashtable)registry.get(extension);
if (keyTable == null) {
keyTable = new Hashtable();
registry.put(extension, keyTable);
}
keyTable.put(key, value);
}
/**
* @see IFileTypeRegistry#containsKey
*/
public boolean containsKey(String extension, String key) {
Hashtable keyTable = (Hashtable)registry.get(extension);
if (keyTable == null) return false;
return ((Hashtable)keyTable).containsKey(key);
}
/**
* Reads the ASCII patterns currently defined by extensions.
*/
private void initializePluginPatterns() {
TeamPlugin plugin = TeamPlugin.getPlugin();
if (plugin != null) {
IExtensionPoint extension = plugin.getDescriptor().getExtensionPoint(TeamPlugin.FILE_TYPES_EXTENSION);
if (extension != null) {
IExtension[] extensions = extension.getExtensions();
for (int i = 0; i < extensions.length; i++) {
IConfigurationElement[] configElements = extensions[i].getConfigurationElements();
for (int j = 0; j < configElements.length; j++) {
String ext = configElements[j].getAttribute("extension");
if (ext != null) {
String key = configElements[j].getAttribute("key");
String value = configElements[j].getAttribute("value");
// if this pattern doesn't already exist, add it to the registry
if (!containsKey(ext, key)) {
setValue(ext, key, value);
}
}
}
}
}
}
}
/**
* Read the saved file type state from the given input stream.
*
* @param dis the input stream to read the saved state from
* @throws IOException if an I/O problem occurs
*/
private void readState(DataInputStream dis) throws IOException {
registry = new Hashtable(11);
int extensionCount = 0;
try {
extensionCount = dis.readInt();
} catch (EOFException e) {
// Ignore the exception, it will occur if there are no
// patterns stored in the state file.
return;
}
for (int i = 0; i < extensionCount; i++) {
String extension = dis.readUTF();
int keyCount = dis.readInt();
for (int j = 0; j < keyCount; j++) {
String key = dis.readUTF();
String value = dis.readUTF();
setValue(extension, key, value);
}
}
}
/**
* Write the currentstate to the given output stream.
*
* @param dos the output stream to write the saved state to
* @throws IOException if an I/O problem occurs
*/
private void writeState(DataOutputStream dos) throws IOException {
dos.writeInt(registry.size());
Iterator it = registry.keySet().iterator();
while (it.hasNext()) {
String extension = (String)it.next();
dos.writeUTF(extension);
Hashtable keyTable = (Hashtable)registry.get(extension);
dos.writeInt(keyTable.size());
Iterator keyIt = keyTable.keySet().iterator();
while (keyIt.hasNext()) {
String key = (String)keyIt.next();
dos.writeUTF(key);
dos.writeUTF((String)keyTable.get(key));
}
}
}
/**
* Load the file type registry saved state. This loads the previously saved
* contents, as well as discovering any values contributed by plug-ins.
*/
private void loadPluginState() {
IPath pluginStateLocation = TeamPlugin.getPlugin().getStateLocation().append(STATE_FILE);
File f = pluginStateLocation.toFile();
if (f.exists()) {
try {
DataInputStream dis = new DataInputStream(new FileInputStream(f));
readState(dis);
dis.close();
} catch (IOException ex) {
// Throw an exception here
}
}
// Read values contributed by plugins
initializePluginPatterns();
}
/**
* Save the file type registry state.
*/
private void savePluginState() {
IPath pluginStateLocation = TeamPlugin.getPlugin().getStateLocation();
File tempFile = pluginStateLocation.append(STATE_FILE + ".tmp").toFile();
File stateFile = pluginStateLocation.append(STATE_FILE).toFile();
try {
DataOutputStream dos = new DataOutputStream(new FileOutputStream(tempFile));
writeState(dos);
dos.close();
if (stateFile.exists() && !stateFile.delete()) {
// Throw an exception here
}
boolean renamed = tempFile.renameTo(stateFile);
if (!renamed) {
// Throw an exception here
}
} catch (Exception e) {
// Throw an exception here
}
}
}