blob: 30bcabd9c740cc86651d9d1675fb09a73a0b15fe [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.osgi.framework.internal.defaultadaptor;
import java.io.*;
import java.util.Enumeration;
import java.util.Hashtable;
import org.eclipse.osgi.framework.adaptor.PermissionStorage;
import org.eclipse.osgi.framework.adaptor.core.AdaptorMsg;
import org.eclipse.osgi.framework.debug.Debug;
import org.eclipse.osgi.framework.internal.reliablefile.*;
/**
* Class to model permission data storage.
*/
//TODO switch this class over to use MetaData instead of ReliableFile
class DefaultPermissionStorage implements PermissionStorage {
/** Directory into which permission data files are stored. */
protected File permissionDir;
/** List of permission files: String location => File permission file */
protected Hashtable permissionFiles;
/** Default permission data. */
protected File defaultData;
/** First permission data format version */
protected static final int PERMISSIONDATA_VERSION_1 = 1;
/** Current permission data format version */
protected static final int PERMISSIONDATA_VERSION = PERMISSIONDATA_VERSION_1;
/**
* Constructor.
*
* @throws IOException If an error occurs initializing the object.
*/
protected DefaultPermissionStorage(DefaultAdaptor adaptor) throws IOException {
permissionDir = new File(adaptor.getBundleStoreRootDir(), "permdata");
permissionFiles = new Hashtable();
if (!permissionDir.exists() && !permissionDir.mkdirs()) {
if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
Debug.println("Unable to create directory: " + permissionDir.getPath());
}
throw new IOException(AdaptorMsg.formatter.getString("ADAPTOR_STORAGE_EXCEPTION"));
}
defaultData = new File(permissionDir, ".default");
loadLocations();
}
/**
* Returns the locations that have permission data assigned to them,
* that is, locations for which permission data
* exists in persistent storage.
*
* @return The locations that have permission data in
* persistent storage, or <tt>null</tt> if there is no permission data
* in persistent storage.
* @throws IOException If a failure occurs accessing peristent storage.
*/
public synchronized String[] getLocations() throws IOException {
int size = permissionFiles.size();
if (size == 0) {
return null;
}
String[] locations = new String[size];
Enumeration enum = permissionFiles.keys();
for (int i = 0; i < size; i++) {
locations[i] = (String) enum.nextElement();
}
return locations;
}
/**
* Gets the permission data assigned to the specified
* location.
*
* @param location The location whose permission data is to
* be returned.
*
* @return The permission data assigned to the specified
* location, or <tt>null</tt> if that location has not been assigned any
* permission data.
* @throws IOException If a failure occurs accessing peristent storage.
*/
public synchronized String[] getPermissionData(String location) throws IOException {
File file;
if (location == null) {
file = defaultData;
} else {
file = (File) permissionFiles.get(location);
if (file == null) {
return null;
}
}
try {
return readData(file);
} catch (FileNotFoundException e) {
return null;
}
}
/**
* Assigns the specified permission data to the specified
* location.
*
* @param location The location that will be assigned the
* permissions.
* @param data The permission data to be assigned, or <tt>null</tt>
* if the specified location is to be removed from persistent storaqe.
* @throws IOException If a failure occurs modifying peristent storage.
*/
public synchronized void setPermissionData(String location, String[] data) throws IOException {
File file;
if (location == null) {
file = defaultData;
if (data == null) {
ReliableFile.delete(defaultData);
} else {
save(defaultData, null, data); /* Save the value in persistent storage */
}
} else {
file = (File) permissionFiles.get(location);
if (data == null) {
if (file == null) {
return;
}
permissionFiles.remove(location);
ReliableFile.delete(file);
} else {
file = save(file, location, data); /* Save the value in persistent storage */
permissionFiles.put(location, file);
}
}
}
/**
* Load the locations for which permission data exists.
*
* @throws IOException If an error occurs reading the files.
*/
protected void loadLocations() throws IOException {
String list[] = permissionDir.list();
int len = list.length;
for (int i = 0; i < len; i++) {
String name = list[i];
if (name.endsWith(ReliableFile.newExt)) {
continue;
}
if (name.endsWith(ReliableFile.oldExt)) {
continue;
}
if (name.endsWith(ReliableFile.tmpExt)) {
continue;
}
File file = new File(permissionDir, name);
try {
String location = readLocation(file);
if (location != null) {
permissionFiles.put(location, file);
}
} catch (FileNotFoundException e) {
/* the file should have been there */
}
}
}
/**
* Read the location from the specified file.
*
* @param file File to read the location from.
* @return Location from the file or null if the file is unknown.
* @throws IOException If an error occurs reading the file.
* @throws FileNotFoundException if the data file does not exist.
*/
private String readLocation(File file) throws IOException {
DataInputStream in = new DataInputStream(new ReliableFileInputStream(file));
try {
int version = in.readInt();
switch (version) {
case PERMISSIONDATA_VERSION_1 :
{
boolean locationPresent = in.readBoolean();
if (locationPresent) {
String location = in.readUTF();
return location;
}
break;
}
default :
{
throw new IOException(AdaptorMsg.formatter.getString("ADAPTOR_STORAGE_EXCEPTION"));
}
}
} finally {
in.close();
}
return null;
}
/**
* Read the permission data from the specified file.
*
* @param file File to read the permission data from.
* @throws IOException If an error occurs reading the file.
* @throws FileNotFoundException if the data file does not exist.
*/
private String[] readData(File file) throws IOException {
DataInputStream in = new DataInputStream(new ReliableFileInputStream(file));
try {
int version = in.readInt();
switch (version) {
case PERMISSIONDATA_VERSION_1 :
{
boolean locationPresent = in.readBoolean();
if (locationPresent) {
String location = in.readUTF();
}
int size = in.readInt();
String[] data = new String[size];
for (int i = 0; i < size; i++) {
data[i] = in.readUTF();
}
return data;
}
default :
{
throw new IOException(AdaptorMsg.formatter.getString("ADAPTOR_STORAGE_EXCEPTION"));
}
}
} finally {
in.close();
}
}
/**
* Save the permission data for the specified key.
* This assumes an attempt has been made to load
* the specified key just prior to calling save.
*
* @param key Key to save the permission data for.
*/
protected File save(File file, String location, String[] data) throws IOException {
if (file == null) /* we need to create a filename */{
file = File.createTempFile("perm", "", permissionDir);
file.delete(); /* delete the empty file */
}
int size = data.length;
DataOutputStream out = new DataOutputStream(new ReliableFileOutputStream(file));
try {
out.writeInt(PERMISSIONDATA_VERSION);
if (location == null) {
out.writeBoolean(false);
} else {
out.writeBoolean(true);
out.writeUTF(location);
}
out.writeInt(size);
for (int i = 0; i < size; i++) {
out.writeUTF(data[i]);
}
} finally {
out.close();
}
return file;
}
}