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 | |
} | |
} | |
} |