You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by dp...@apache.org on 2008/03/26 12:03:28 UTC
svn commit: r641251 - in
/jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal:
FileJournal.java RotatingLogFile.java
Author: dpfister
Date: Wed Mar 26 04:03:25 2008
New Revision: 641251
URL: http://svn.apache.org/viewvc?rev=641251&view=rev
Log:
JCR-1502 - Journal log file rotation overwrites old files
Added:
jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/RotatingLogFile.java
Modified:
jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/FileJournal.java
Modified: jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/FileJournal.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/FileJournal.java?rev=641251&r1=641250&r2=641251&view=diff
==============================================================================
--- jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/FileJournal.java (original)
+++ jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/FileJournal.java Wed Mar 26 04:03:25 2008
@@ -21,11 +21,8 @@
import org.slf4j.LoggerFactory;
import java.io.File;
-import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
-import java.util.Arrays;
-import java.util.Comparator;
/**
* File-based journal implementation that appends journal records to a single
@@ -114,10 +111,10 @@
maximumSize = DEFAULT_MAXSIZE;
}
rootDirectory = new File(directory);
-
+
// JCR-1341: Cluster Journal directory should be created automatically
rootDirectory.mkdirs();
-
+
if (!rootDirectory.exists() || !rootDirectory.isDirectory()) {
String msg = "Directory specified does either not exist " +
"or is not a directory: " + directory;
@@ -145,22 +142,16 @@
long stopRevision = getRevision();
- File[] logFiles = null;
+ File[] files = null;
if (startRevision < stopRevision) {
- logFiles = rootDirectory.listFiles(new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.startsWith(basename + ".");
- }
- });
- Arrays.sort(logFiles, new Comparator() {
- public int compare(Object o1, Object o2) {
- File f1 = (File) o1;
- File f2 = (File) o2;
- return f1.compareTo(f2);
- }
- });
+ RotatingLogFile[] logFiles = RotatingLogFile.listFiles(rootDirectory, basename);
+ files = new File[logFiles.length];
+ for (int i = 0; i < files.length; i++) {
+ files[i] = logFiles[i].getFile();
+ }
}
- return new FileRecordIterator(logFiles, startRevision, stopRevision, getResolver(), getNamePathResolver());
+ return new FileRecordIterator(files, startRevision, stopRevision,
+ getResolver(), getNamePathResolver());
}
/**
@@ -179,7 +170,7 @@
try {
FileRecordLog recordLog = new FileRecordLog(journalFile);
if (recordLog.exceeds(maximumSize)) {
- switchLogs();
+ rotateLogs();
recordLog = new FileRecordLog(journalFile);
}
if (recordLog.isNew()) {
@@ -244,39 +235,11 @@
* <code>journal.(N+1).log</code>, whereas the main journal file gets renamed
* to <code>journal.1.log</code>.
*/
- private void switchLogs() {
- FilenameFilter filter = new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.startsWith(basename + ".");
- }
- };
- File[] files = rootDirectory.listFiles(filter);
- Arrays.sort(files, new Comparator() {
- public int compare(Object o1, Object o2) {
- File f1 = (File) o1;
- File f2 = (File) o2;
- return f2.compareTo(f1);
- }
- });
- for (int i = 0; i < files.length; i++) {
- File file = files[i];
- String name = file.getName();
- int sep = name.lastIndexOf('.');
- if (sep != -1) {
- String ext = name.substring(sep + 1);
- if (ext.equals(LOG_EXTENSION)) {
- file.renameTo(new File(rootDirectory, name + ".1"));
- } else {
- try {
- int version = Integer.parseInt(ext);
- String newName = name.substring(0, sep + 1) +
- String.valueOf(version + 1);
- file.renameTo(new File(rootDirectory, newName));
- } catch (NumberFormatException e) {
- log.warn("Bogusly named journal file, skipped: " + file);
- }
- }
- }
+ private void rotateLogs() {
+ RotatingLogFile[] logFiles = RotatingLogFile.listFiles(rootDirectory, basename);
+ for (int i = 0; i < logFiles.length; i++) {
+ logFiles[i].rotate();
}
}
+
}
Added: jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/RotatingLogFile.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/RotatingLogFile.java?rev=641251&view=auto
==============================================================================
--- jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/RotatingLogFile.java (added)
+++ jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/RotatingLogFile.java Wed Mar 26 04:03:25 2008
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.journal;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents a log file that can be rotated.
+ */
+public class RotatingLogFile implements Comparable {
+
+ /**
+ * Logger.
+ */
+ private static Logger log = LoggerFactory.getLogger(RotatingLogFile.class);
+
+ /**
+ * Log extension.
+ */
+ private static final String LOG_EXTENSION = "log";
+
+ /**
+ * Parent directory.
+ */
+ private final File directory;
+
+ /**
+ * Basename.
+ */
+ private final String basename;
+
+ /**
+ * Backing file.
+ */
+ private final File file;
+
+ /**
+ * Version number.
+ */
+ private int version;
+
+ /**
+ * Create a new instance of this class.
+ *
+ * @param file file itself
+ * @throws IllegalArgumentException if the filename is malformed
+ */
+ private RotatingLogFile(File directory, String basename, File file)
+ throws IllegalArgumentException {
+
+ this.directory = directory;
+ this.basename = basename;
+ this.file = file;
+
+ parseName();
+ }
+
+ /**
+ * Parse the file name, ensuring that the file is actually made up
+ * of the components we expect.
+ *
+ * @throws IllegalArgumentException if the name is malformed
+ */
+ private void parseName() throws IllegalArgumentException {
+ String name = file.getName();
+ int sep1 = name.indexOf('.');
+ if (sep1 == -1) {
+ throw new IllegalArgumentException("no dot in filename.");
+ }
+ if (!basename.equals(name.substring(0, sep1))) {
+ throw new IllegalArgumentException("name does not start with " +
+ basename + ".");
+ }
+ int sep2 = name.indexOf('.', sep1 + 1);
+ if (sep2 == -1) {
+ sep2 = name.length();
+ }
+ if (!LOG_EXTENSION.equals(name.substring(sep1 + 1, sep2))) {
+ throw new IllegalArgumentException("name does not contain " +
+ LOG_EXTENSION + ".");
+ }
+ if (sep2 < name.length()) {
+ String versionS = name.substring(sep2 + 1);
+ try {
+ version = Integer.parseInt(versionS);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(
+ "extension is not a number: " + versionS);
+ }
+ }
+ }
+
+ /**
+ * Return the backing file.
+ */
+ public File getFile() {
+ return file;
+ }
+
+ /**
+ * Rotate this file.
+ */
+ public void rotate() {
+ String newName = basename +
+ "." + LOG_EXTENSION +
+ "." + String.valueOf(version + 1);
+ file.renameTo(new File(directory, newName));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int compareTo(Object o) {
+ return compareTo((RotatingLogFile) o);
+ }
+
+ /**
+ * Compares this log file to another file. It will return
+ * a negative number if this log file has a smaller version,
+ * a positive number if this log file a bigger version
+ * and <code>0</code> if they have the same version.
+ */
+ public int compareTo(RotatingLogFile o) {
+ return version - o.version;
+ }
+
+ /**
+ * List all log files inside some directory. The list returned is
+ * guaranteed to be in descending order, i.e. it is safe to rotate
+ * every file in turn without accidentally overwriting another one.
+ *
+ * @param directory parent directory
+ * @param basename basename expected
+ * @return array of log files found
+ */
+ public static RotatingLogFile[] listFiles(File directory, final String basename) {
+ File[] files = directory.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.startsWith(basename + ".");
+ }
+ });
+
+ ArrayList l = new ArrayList();
+ for (int i = 0; i < files.length; i++) {
+ File file = files[i];
+ try {
+ l.add(new RotatingLogFile(directory, basename, file));
+ } catch (IllegalArgumentException e) {
+ log.warn("Bogusly named journal file, skipped: " + files[i] +
+ ", reason: " + e.getMessage());
+ }
+ }
+ RotatingLogFile[] logFiles = new RotatingLogFile[l.size()];
+ l.toArray(logFiles);
+
+ Arrays.sort(logFiles, new Comparator() {
+ public int compare(Object o1, Object o2) {
+ RotatingLogFile lf1 = (RotatingLogFile) o1;
+ RotatingLogFile lf2 = (RotatingLogFile) o2;
+ return lf2.compareTo(lf1);
+ }
+ });
+ return logFiles;
+ }
+}