/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.hibernate.eclipse.logging;
import java.io.IOException;
import org.apache.log4j.Layout;
import org.apache.log4j.RollingFileAppender;
import org.apache.log4j.spi.LoggingEvent;
import org.eclipse.core.runtime.IPath;
import org.hibernate.console.ConsoleMessages;
/**
* 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(ConsoleMessages.PluginFileAppender_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();
}
public void append(LoggingEvent event) {
super.append( event );
}
}