blob: b33faf3a0d17bdd9f3250b53ace9cf0de500fc21 [file] [log] [blame]
/**********************************************************************
* Copyright (c) 2000, 2004 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.core.internal.runtime;
import java.io.*;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.*;
import org.osgi.framework.Bundle;
public class DataArea {
/* package */static final String F_DESCRIPTION = ".platform"; //$NON-NLS-1$
/* package */static final String F_META_AREA = ".metadata"; //$NON-NLS-1$
/* package */static final String F_PLUGIN_PATH = ".plugin-path"; //$NON-NLS-1$
/* package */static final String F_PLUGIN_DATA = ".plugins"; //$NON-NLS-1$
/* package */static final String F_LOG = ".log"; //$NON-NLS-1$
/* package */static final String F_BACKUP = ".bak"; //$NON-NLS-1$
/* package */static final String F_KEYRING = ".keyring"; //$NON-NLS-1$
/* package */static final String F_LOCK_FILE = ".lock"; //$NON-NLS-1$
/* package */static final String F_VERSION = "version.ini"; //$NON-NLS-1$
/**
* Internal name of the preference storage file (value <code>"pref_store.ini"</code>) in this plug-in's (read-write) state area.
*/
/* package */static final String PREFERENCES_FILE_NAME = "pref_store.ini"; //$NON-NLS-1$
private IPath location; //The location of the instance data
private boolean locationCreated = false;
private IPath tmpLog; //The name of the temporary log file
private PlatformMetaAreaLock metaAreaLock = null;
//Authorization related informations
private AuthorizationDatabase keyring = null;
private long keyringTimeStamp;
private String keyringFile = null;
private String password = ""; //$NON-NLS-1$
private boolean initialized = false;
public boolean hasInstanceData() {
return isInstanceDataLocationInitiliazed();
}
boolean isInstanceDataLocationInitiliazed() {
return location != null && initialized;
}
protected void assertLocationInitialized() throws IllegalStateException {
try {
if (location == null || ! initialized)
initializeLocation();
if (!locationCreated)
createLocation();
} catch (CoreException e) {
throw new IllegalStateException(e.getMessage());
}
if (!isInstanceDataLocationInitiliazed()) {
throw new IllegalStateException(Policy.bind("meta.instanceDataUnspecified")); //$NON-NLS-1$
}
}
public IPath getBackupFilePathFor(IPath file) throws IllegalStateException {
assertLocationInitialized();
return file.removeLastSegments(1).append(file.lastSegment() + F_BACKUP);
}
public IPath getMetadataLocation() throws IllegalStateException {
assertLocationInitialized();
return location.append(F_META_AREA);
}
public IPath getInstanceDataLocation() throws IllegalStateException {
assertLocationInitialized();
return location;
}
public IPath getLogLocation() throws IllegalStateException {
if (!isInstanceDataLocationInitiliazed()) {
return getTemporaryLogLocation();
}
if (tmpLog != null) {
copyOldLog(getTemporaryLogLocation(), getMetadataLocation().append(F_LOG));
tmpLog = null;
}
return getMetadataLocation().append(F_LOG);
}
protected IPath getTemporaryLogLocation() {
if (tmpLog == null)
tmpLog = InternalPlatform.getDefault().getConfigurationMetadataLocation().append(Long.toString(System.currentTimeMillis()) + F_LOG);
return tmpLog;
}
private void copyOldLog(IPath from, IPath to) {
File source = from.toFile();
if (!source.exists())
return;
InputStream input = null;
OutputStream output = null;
try {
input = new FileInputStream(source);
output = new FileOutputStream(to.toFile(), true);
transferStreams(input, output);
} catch (IOException e) {
} finally {
try {
if (input != null)
input.close();
if (output != null)
output.close();
} catch(IOException e) {
}
}
}
private void transferStreams(InputStream source, OutputStream destination) throws IOException {
source = new BufferedInputStream(source);
destination = new BufferedOutputStream(destination);
try {
byte[] buffer = new byte[8192];
while (true) {
int bytesRead = -1;
if ((bytesRead = source.read(buffer)) == -1)
break;
destination.write(buffer, 0, bytesRead);
}
} finally {
try {
source.close();
} catch (IOException e) {
}
try {
destination.close();
} catch (IOException e) {
}
}
}
/**
* Returns the read/write location in which the given bundle can manage private state.
*/
public IPath getStateLocation(Bundle bundle) throws IllegalStateException {
assertLocationInitialized();
return getMetadataLocation().append(F_PLUGIN_DATA).append(bundle.getGlobalName());
}
/**
* Returns the read/write location of the file for storing plugin preferences.
*/
public IPath getPreferenceLocation(Bundle bundle, boolean create) throws IllegalStateException {
assertLocationInitialized();
IPath result = getStateLocation(bundle);
if (create)
result.toFile().mkdirs();
return result.append(PREFERENCES_FILE_NAME);
}
/**
* Return the path to the version.ini file.
*/
public IPath getVersionPath() throws IllegalStateException {
assertLocationInitialized();
return getMetadataLocation().append(F_VERSION);
}
public void setInstanceDataLocation(IPath loc) throws IllegalStateException {
if (isInstanceDataLocationInitiliazed())
throw new IllegalStateException(Policy.bind("meta.instanceDataAlreadySpecified", loc.toOSString()));
location = loc;
}
protected void initializeLocation() throws CoreException {
if (location == null) {
// Default location for the workspace is <user.dir>/workspace/
location = new Path(System.getProperty("user.dir")).append(InternalPlatform.WORKSPACE); //$NON-NLS-1$
}
// check if the location can be created
if (location.toFile().exists()) {
if (!location.toFile().isDirectory()) {
String message = Policy.bind("meta.notDir", location.toString()); //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, Platform.PI_RUNTIME, IPlatform.FAILED_WRITE_METADATA, message, null));
}
}
//try infer the device if there isn't one (windows)
if (location.getDevice() == null)
location = new Path(location.toFile().getAbsolutePath());
initialized = true;
}
private void createLocation() throws CoreException {
File file = location.toFile();
try {
file.mkdirs();
} catch (Exception e) {
String message = Policy.bind("meta.couldNotCreate", file.getAbsolutePath()); //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, IPlatform.PI_RUNTIME, IPlatform.FAILED_WRITE_METADATA, message, e));
}
if (!file.canWrite()) {
String message = Policy.bind("meta.readonly", file.getAbsolutePath()); //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, IPlatform.PI_RUNTIME, IPlatform.FAILED_WRITE_METADATA, message, null));
}
locationCreated = true;
}
/**
* Creates a lock file in the meta-area that indicates the meta-area is in use, preventing other eclipse instances from concurrently using the same meta-area.
*/
public synchronized void createLockFile() throws CoreException, IllegalStateException {
assertLocationInitialized();
if (System.getProperty("org.eclipse.core.runtime.ignoreLockFile") != null) //$NON-NLS-1$
return;
String lockLocation = getMetadataLocation().append(F_LOCK_FILE).toOSString();
metaAreaLock = new PlatformMetaAreaLock(new File(lockLocation));
try {
if (!metaAreaLock.acquire()) {
String message = Policy.bind("meta.inUse", lockLocation); //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, IPlatform.PI_RUNTIME, IPlatform.FAILED_WRITE_METADATA, message, null));
}
} catch (IOException e) {
String message = Policy.bind("meta.failCreateLock", lockLocation); //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, IPlatform.PI_RUNTIME, IPlatform.FAILED_WRITE_METADATA, message, e));
}
}
/**
* Closes the open lock file handle, and makes a silent best attempt to delete the file.
*/
public synchronized void clearLockFile() throws IllegalStateException {
assertLocationInitialized();
if (metaAreaLock != null)
metaAreaLock.release();
}
/**
* @see Platform
*/
public void addAuthorizationInfo(URL serverUrl, String realm, String authScheme, Map info) throws CoreException {
loadKeyring();
keyring.addAuthorizationInfo(serverUrl, realm, authScheme, new HashMap(info));
keyring.save();
}
/**
* @see Platform
*/
public void addProtectionSpace(URL resourceUrl, String realm) throws CoreException {
loadKeyring();
keyring.addProtectionSpace(resourceUrl, realm);
keyring.save();
}
/**
* @see Platform
*/
public void flushAuthorizationInfo(URL serverUrl, String realm, String authScheme) throws CoreException {
loadKeyring();
keyring.flushAuthorizationInfo(serverUrl, realm, authScheme);
keyring.save();
}
/**
* @see Platform
*/
public Map getAuthorizationInfo(URL serverUrl, String realm, String authScheme) {
loadKeyring();
Map info = keyring.getAuthorizationInfo(serverUrl, realm, authScheme);
return info == null ? null : new HashMap(info);
}
/**
* @see Platform
*/
public String getProtectionSpace(URL resourceUrl) {
loadKeyring();
return keyring.getProtectionSpace(resourceUrl);
}
/**
* Opens the password database (if any) initally provided to the platform at startup.
*/
private void loadKeyring() {
if (keyring != null && new File(keyringFile).lastModified()==keyringTimeStamp)
return;
if (keyringFile == null) {
keyringFile = InternalPlatform.getDefault().getConfigurationMetadataLocation().append(F_KEYRING).toOSString();
}
try {
keyring = new AuthorizationDatabase(keyringFile, password);
} catch (CoreException e) {
InternalPlatform.getDefault().log(e.getStatus());
}
if (keyring == null) {
//try deleting the file and loading again - format may have changed
new java.io.File(keyringFile).delete();
try {
keyring = new AuthorizationDatabase(keyringFile, password);
} catch (CoreException e) {
//don't bother logging a second failure
}
}
keyringTimeStamp = new File(keyringFile).lastModified();
}
public void setKeyringFile(String keyringFile) {
if (this.keyringFile != null)
throw new IllegalStateException(Policy.bind("meta.keyringFileAlreadySpecified", this.keyringFile));
this.keyringFile = keyringFile;
}
public void setPasswork(String password) {
this.password = password;
}
}