Return-Path: Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: (qmail 99751 invoked from network); 26 Mar 2008 11:03:55 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 26 Mar 2008 11:03:55 -0000 Received: (qmail 26160 invoked by uid 500); 26 Mar 2008 11:03:50 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 26135 invoked by uid 500); 26 Mar 2008 11:03:50 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 26123 invoked by uid 99); 26 Mar 2008 11:03:50 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 26 Mar 2008 04:03:50 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 26 Mar 2008 11:03:18 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 6A8161A9838; Wed, 26 Mar 2008 04:03:30 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r641251 - in /jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal: FileJournal.java RotatingLogFile.java Date: Wed, 26 Mar 2008 11:03:28 -0000 To: commits@jackrabbit.apache.org From: dpfister@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080326110330.6A8161A9838@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 @@ * journal.(N+1).log, whereas the main journal file gets renamed * to journal.1.log. */ - 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 0 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; + } +}