001: package logging;
002:
003: import java.io.IOException;
004:
005: import org.apache.log4j.Layout;
006: import org.apache.log4j.RollingFileAppender;
007: import org.eclipse.core.runtime.IPath;
008:
009: /**
010: * PluginFileAppender
011: * This class is a custom Log4J appender that sends Log4J events to
012: * the Eclipse plug-in state location. It extends the RollingFileAppender class.
013: * @author Manoel Marques
014: */
015: public class PluginFileAppender extends RollingFileAppender {
016:
017: private IPath stateLocation;
018: private boolean activateOptionsPending;
019: private boolean translatePath = true;
020:
021: /**
022: * Creates a new PluginFileAppender.
023: */
024: public PluginFileAppender() {
025: super ();
026: }
027:
028: /**
029: * Creates a new PluginFileAppender.
030: * @param layout layout instance.
031: * @param stateLocation IPath containing the plug-in state location
032: */
033: public PluginFileAppender(Layout layout, IPath stateLocation) {
034: super ();
035: setLayout(layout);
036: setStateLocation(stateLocation);
037: }
038:
039: /**
040: * Creates a new PluginFileAppender.
041: * @param layout layout instance.
042: * @param stateLocation IPath containing the plug-in state location
043: * @param file file name
044: * @param append true if file is to be appended
045: */
046: public PluginFileAppender(Layout layout, IPath stateLocation,
047: String file, boolean append) throws IOException {
048: super ();
049: setLayout(layout);
050: setStateLocation(stateLocation);
051: setFile(file);
052: setAppend(append);
053: activateOptions();
054: }
055:
056: /**
057: * Creates a new PluginFileAppender.
058: * @param layout layout instance.
059: * @param stateLocation IPath containing the plug-in state location
060: * @param file file name
061: */
062: public PluginFileAppender(Layout layout, IPath stateLocation,
063: String file) throws IOException {
064: super ();
065: setLayout(layout);
066: setStateLocation(stateLocation);
067: setFile(file);
068: activateOptions();
069: }
070:
071: /**
072: * Sets the state location. If activateOptions call is pending, translate the file name
073: * and call activateOptions
074: * @param stateLocation IPath containing the plug-in state location
075: */
076: void setStateLocation(IPath stateLocation) {
077: this .stateLocation = stateLocation;
078: if (this .stateLocation != null && this .activateOptionsPending) {
079: this .activateOptionsPending = false;
080: setFile(getFile());
081: activateOptions();
082: }
083: }
084:
085: /**
086: * Sets the file name.Translate it before setting.
087: * @param file file name
088: */
089: public void setFile(String file) {
090: super .setFile(getTranslatedFileName(file));
091: }
092:
093: /**
094: * Set file options and opens it, leaving ready to write.
095: * @param file file name
096: * @param append true if file is to be appended
097: * @param bufferedIO true if file is to buffered
098: * @param bufferSize buffer size
099: * @throws IOException - IO Error happend or the state location was not set
100: */
101: public void setFile(String fileName, boolean append,
102: boolean bufferedIO, int bufferSize) throws IOException {
103: if (this .stateLocation == null)
104: throw new IOException("Missing Plugin State Location.");
105:
106: fileName = (this .translatePath) ? getTranslatedFileName(fileName)
107: : fileName;
108: super .setFile(fileName, append, bufferedIO, bufferSize);
109: }
110:
111: /**
112: * Finishes instance initialization. If state location was not set, set activate as
113: * pending and does nothing.
114: */
115: public void activateOptions() {
116: if (this .stateLocation == null) {
117: this .activateOptionsPending = true;
118: return;
119: }
120:
121: // base class will call setFile, don't translate the name
122: // because it was already translated
123: this .translatePath = false;
124: super .activateOptions();
125: this .translatePath = true;
126: }
127:
128: /**
129: * Any path part of a file is removed and the state location is added to the name
130: * to form a new path. If there is not state location, returns the name unmodified.
131: * @param file file name
132: * @return translated file name
133: */
134: private String getTranslatedFileName(String file) {
135:
136: if (this .stateLocation == null || file == null)
137: return file;
138:
139: file = file.trim();
140: if (file.length() == 0)
141: return file;
142:
143: int index = file.lastIndexOf('/');
144: if (index == -1)
145: index = file.lastIndexOf('\\');
146:
147: if (index != -1)
148: file = file.substring(index + 1);
149:
150: IPath newPath = this.stateLocation.append(file);
151: return newPath.toString();
152: }
153: }
|