/******************************************************************************* * Copyright (c) 2008 Pierre-Antoine Grégoire. * 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: * Pierre-Antoine Grégoire - initial API and implementation *******************************************************************************/ package org.org.eclipse.core.utils.platform.tools.logging; import java.io.IOException; import org.apache.log4j.Layout; import org.apache.log4j.RollingFileAppender; import org.eclipse.core.runtime.IPath; /** * PluginFileAppender * This class is a custom Log4J appender that sends Log4J events to * the Eclipse plug-in state location. It extends the RollingFileAppender class. * @author Manoel Marques */ public class PluginFileAppender extends RollingFileAppender { private IPath stateLocation; private boolean activateOptionsPending; private boolean translatePath = true; /** * Creates a new PluginFileAppender. */ public PluginFileAppender() { super(); } /** * Creates a new PluginFileAppender. * @param layout layout instance. * @param stateLocation IPath containing the plug-in state location */ public PluginFileAppender(Layout layout,IPath stateLocation) { super(); setLayout(layout); setStateLocation(stateLocation); } /** * Creates a new PluginFileAppender. * @param layout layout instance. * @param stateLocation IPath containing the plug-in state location * @param file file name * @param append true if file is to be appended */ public PluginFileAppender(Layout layout,IPath stateLocation, String file, boolean append) throws IOException { super(); setLayout(layout); setStateLocation(stateLocation); setFile(file); setAppend(append); activateOptions(); } /** * Creates a new PluginFileAppender. * @param layout layout instance. * @param stateLocation IPath containing the plug-in state location * @param file file name */ public PluginFileAppender(Layout layout,IPath stateLocation, String file) throws IOException { super(); setLayout(layout); setStateLocation(stateLocation); setFile(file); activateOptions(); } /** * Sets the state location. If activateOptions call is pending, translate the file name * and call activateOptions * @param stateLocation IPath containing the plug-in state location */ void setStateLocation(IPath stateLocation) { this.stateLocation = stateLocation; if (this.stateLocation != null && this.activateOptionsPending) { this.activateOptionsPending = false; setFile(getFile()); activateOptions(); } } /** * Sets the file name.Translate it before setting. * @param file file name */ public void setFile(String file) { super.setFile(getTranslatedFileName(file)); } /** * Set file options and opens it, leaving ready to write. * @param file file name * @param append true if file is to be appended * @param bufferedIO true if file is to buffered * @param bufferSize buffer size * @throws IOException - IO Error happend or the state location was not set */ public void setFile(String fileName,boolean append,boolean bufferedIO,int bufferSize) throws IOException { if (this.stateLocation == null) throw new IOException("Missing Plugin State Location."); fileName = (this.translatePath) ? getTranslatedFileName(fileName) : fileName; super.setFile(fileName,append,bufferedIO,bufferSize); } /** * Finishes instance initialization. If state location was not set, set activate as * pending and does nothing. */ public void activateOptions() { if (this.stateLocation == null) { this.activateOptionsPending = true; return; } // base class will call setFile, don't translate the name // because it was already translated this.translatePath = false; super.activateOptions(); this.translatePath = true; } /** * Any path part of a file is removed and the state location is added to the name * to form a new path. If there is not state location, returns the name unmodified. * @param file file name * @return translated file name */ private String getTranslatedFileName(String file) { if (this.stateLocation == null || file == null) return file; file = file.trim(); if (file.length() == 0) return file; int index = file.lastIndexOf('/'); if (index == -1) index = file.lastIndexOf('\\'); if (index != -1) file = file.substring(index + 1); IPath newPath = this.stateLocation.append(file); return newPath.toString(); } }