/******************************************************************************* * 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; } }