blob: d87764b0c13cc431b92b27b419948b85507d137b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2008 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.update.internal.core;
import java.io.*;
import java.net.URL;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.update.configurator.ConfiguratorUtils;
import org.eclipse.update.configurator.IPlatformConfiguration;
import org.eclipse.update.core.Utilities;
/**
* Manages the error/recover log file
*/
public class ErrorRecoveryLog {
private static final String ERROR_RECOVERY_LOG = "error_recovery.log"; //$NON-NLS-1$
private static final String LOG_ENTRY_KEY = "LogEntry."; //$NON-NLS-1$
private static final String RETURN_CARRIAGE = "\r\n"; //$NON-NLS-1$
private static final String END_OF_FILE = "eof=eof"; //$NON-NLS-1$
//
public static final String START_INSTALL_LOG = "START_INSTALL_LOG"; //$NON-NLS-1$
public static final String PLUGIN_ENTRY = "PLUGIN"; //$NON-NLS-1$
public static final String FRAGMENT_ENTRY = "FRAGMENT"; //$NON-NLS-1$
public static final String BUNDLE_MANIFEST_ENTRY = "BUNDLE_MANIFEST"; //$NON-NLS-1$
public static final String BUNDLE_JAR_ENTRY = "BUNDLE"; //$NON-NLS-1$
public static final String FEATURE_ENTRY = "FEATURE"; //$NON-NLS-1$2
public static final String ALL_INSTALLED = "ALL_FEATURES_INSTALLED"; //$NON-NLS-1$
public static final String RENAME_ENTRY = "RENAME"; //$NON-NLS-1$
public static final String END_INSTALL_LOG = "END_INSTALL_LOG"; //$NON-NLS-1$
public static final String START_REMOVE_LOG = "REMOVE_LOG"; //$NON-NLS-1$
public static final String END_ABOUT_REMOVE = "END_ABOUT_TO_REMOVE"; //$NON-NLS-1$
public static final String DELETE_ENTRY = "DELETE"; //$NON-NLS-1$
public static final String END_REMOVE_LOG = "END_REMOVE_LOG"; //$NON-NLS-1$
private static ErrorRecoveryLog inst;
private FileWriter out;
private int index;
private List paths;
private boolean open = false;
private int nbOfOpen = 0;
/**
* Constructor for ErrorRecoveryLog.
*/
private ErrorRecoveryLog() {
super();
}
/**
* Singleton
*/
public static ErrorRecoveryLog getLog() {
if (inst == null){
inst = new ErrorRecoveryLog();
}
return inst;
}
/**
* get a unique identifer for the file, ensure uniqueness up to now
*/
public static String getLocalRandomIdentifier(String path) {
if (path==null) return null;
// verify if it will be a directory without creating the file
// as it doesn't exist yet
if (path.endsWith(File.separator) || path.endsWith("/")) //$NON-NLS-1$
return path;
File file = new File(path);
String newName =
UpdateManagerUtils.getLocalRandomIdentifier(file.getName(), new Date());
while (new File(file.getParentFile(), newName).exists()) {
newName =
UpdateManagerUtils.getLocalRandomIdentifier(file.getName(), new Date());
}
File newFile = new File(file.getParentFile(),newName);
return newFile.getAbsolutePath();
}
/**
* returns the log file
* We do not check if the file exists
*/
public File getRecoveryLogFile() {
IPlatformConfiguration configuration =
ConfiguratorUtils.getCurrentPlatformConfiguration();
URL location = configuration.getConfigurationLocation();
String locationString = location.getFile();
File platformConfiguration = new File(locationString);
if (!platformConfiguration.isDirectory()) platformConfiguration = platformConfiguration.getParentFile();
return new File(platformConfiguration, ERROR_RECOVERY_LOG);
}
/**
* Open the log
*/
public void open(String logEntry) throws CoreException {
if (open) {
nbOfOpen++;
UpdateCore.warn("Open nested Error/Recovery log #"+nbOfOpen+":"+logEntry); //$NON-NLS-1$ //$NON-NLS-2$
return;
}
File logFile = null;
try {
logFile = getRecoveryLogFile();
out = new FileWriter(logFile);
index = 0;
paths=null;
open=true;
nbOfOpen=0;
UpdateCore.warn("Start new Error/Recovery log #"+nbOfOpen+":"+logEntry); //$NON-NLS-1$ //$NON-NLS-2$
} catch (IOException e) {
throw Utilities.newCoreException(
NLS.bind(Messages.UpdateManagerUtils_UnableToLog, (new Object[] { logFile })),
e);
}
append(logEntry);
}
/**
* Append the string to the log and flush
*/
public void append(String logEntry) throws CoreException {
File logFile = null;
try {
if (!open) {
UpdateCore.warn("Internal Error: The Error/Recovery log is not open:"+logEntry); //$NON-NLS-1$
return;
}
StringBuffer buffer = new StringBuffer(LOG_ENTRY_KEY);
buffer.append(index);
buffer.append("="); //$NON-NLS-1$
buffer.append(logEntry);
buffer.append(RETURN_CARRIAGE);
out.write(buffer.toString());
out.flush();
index++;
} catch (IOException e) {
throw Utilities.newCoreException(
NLS.bind(Messages.UpdateManagerUtils_UnableToLog, (new Object[] { logFile })),
e);
}
}
/**
* Append the string to the log and flush
*/
public void appendPath(String logEntry, String path) throws CoreException {
if (path == null)
return;
StringBuffer buffer = new StringBuffer(logEntry);
buffer.append(" "); //$NON-NLS-1$
buffer.append(path);
append(buffer.toString());
addPath(path);
}
/**
* Close any open recovery log
*/
public void close(String logEntry) throws CoreException {
if (nbOfOpen>0){
UpdateCore.warn("Close nested Error/Recovery log #"+nbOfOpen+":"+logEntry); //$NON-NLS-1$ //$NON-NLS-2$
nbOfOpen--;
return;
}
UpdateCore.warn("Close Error/Recovery log #"+nbOfOpen+":"+logEntry); //$NON-NLS-1$ //$NON-NLS-2$
append(logEntry);
if (out != null) {
try {
out.write(END_OF_FILE);
out.flush();
out.close();
} catch (IOException e) { //eat the exception
} finally {
out = null;
open=false;
}
}
}
/**
* Delete the file from the file system
*/
public void delete() {
//File logFile = getRecoveryLogFile();
getRecoveryLogFile();
//if (logFile.exists())
//logFile.delete();
}
/**
*
*/
private void addPath(String path){
if (paths==null) paths = new ArrayList();
paths.add(path);
}
/*
* creates a Status
*/
private IStatus createStatus(int statusSeverity, String msg, Exception e){
String id =
UpdateCore.getPlugin().getBundle().getSymbolicName();
StringBuffer completeString = new StringBuffer(""); //$NON-NLS-1$
if (msg!=null)
completeString.append(msg);
if (e!=null){
completeString.append("\r\n["); //$NON-NLS-1$
completeString.append(e.toString());
completeString.append("]\r\n"); //$NON-NLS-1$
}
return new Status(statusSeverity, id, IStatus.OK, completeString.toString(), e);
}
/**
* return a multi status,
* the children are the file that couldn't be removed
*/
public IStatus removeFromFileSystem(File file) {
IStatus mainStatus = createStatus(IStatus.OK,"",null); //$NON-NLS-1$
MultiStatus multi = new MultiStatus(mainStatus.getPlugin(),mainStatus.getCode(),"",null); //$NON-NLS-1$
if (!file.exists()){
multi.add(createStatus(IStatus.ERROR,Messages.ErrorRecoveryLog_noFiletoRemove+file,null));
return multi;
}
if (file.isDirectory()) {
String[] files = file.list();
if (files != null) // be careful since file.list() can return null
for (int i = 0; i < files.length; ++i){
multi.addAll(removeFromFileSystem(new File(file, files[i])));
}
}
if (!file.delete()) {
String msg = "Unable to remove file" +file.getAbsolutePath(); //$NON-NLS-1$
multi.add(createStatus(IStatus.ERROR,msg,null));
}
return multi;
}
}