
Author: ceki Date: Thu Aug 6 21:07:24 2009 New Revision: 2415 Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DatePatternToSRegexUtil.java - copied, changed from r2414, /logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DatePatternToRegexUtil.java Removed: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DatePatternToRegexUtil.java Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP.java logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DateTokenConverter.java logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/SequenceToRegex4SDF.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP_Test.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/DatePatternToRegexTest.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java Log: - SizeAndTimeBasedFNATP unit test pass even in case of stop/restart. - code needs some refactoring but essentially seems to work Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP.java Thu Aug 6 21:07:24 2009 @@ -10,7 +10,12 @@ package ch.qos.logback.core.rolling; import java.io.File; +import java.io.FilenameFilter; +import java.util.Arrays; +import java.util.Comparator; import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import ch.qos.logback.core.joran.spi.NoAutoStart; import ch.qos.logback.core.util.FileSize; @@ -25,20 +30,67 @@ @Override public void start() { - // we actualy depend on fields being initialized + // we depend on certain fields having been initialized // in super.start() super.start(); - + // we need to get the correct value of currentPeriodsCounter. // usually the value is 0, unless the appender or the application // is stopped and restarted within the same period - - String regex = tbrp.fileNamePattern.asRegex(dateInCurrentPeriod); - continueHere - + + if (tbrp.getParentsRawFileProperty() == null) { + String sregex = tbrp.fileNamePattern.toSRegex(dateInCurrentPeriod); + String simplifiedRegex = afterLastSlash(sregex); + computeCurrentPeriodsCounter(simplifiedRegex); + } started = true; } + String afterLastSlash(String sregex) { + int i = sregex.lastIndexOf('/'); + if (i == -1) { + return sregex; + } else { + return sregex.substring(i + 1); + } + } + + void computeCurrentPeriodsCounter(final String simplifiedRegex) { + File file = new File(getCurrentPeriodsFileNameWithoutCompressionSuffix()); + + File parentDir = file.getParentFile(); + if (parentDir != null && parentDir.isDirectory()) { + File[] matchingFileArray = parentDir.listFiles(new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.matches(simplifiedRegex); + } + }); + if (matchingFileArray == null || matchingFileArray.length == 0) { + return; + } + Arrays.sort(matchingFileArray, new Comparator<File>() { + public int compare(File o1, File o2) { + String o1Name = o1.getName(); + String o2Name = o2.getName(); + return (o2Name.compareTo(o1Name)); + } + }); + File lastFile = matchingFileArray[0]; + + Pattern p = Pattern.compile(simplifiedRegex); + String lastFileName = lastFile.getName(); + + Matcher m = p.matcher(lastFileName); + if (!m.matches()) { + throw new IllegalStateException("The regex [" + simplifiedRegex + + "] should match [" + lastFileName + "]"); + } + String currentPeriodsCounterAsStr = m.group(1); + currentPeriodsCounter = new Integer(currentPeriodsCounterAsStr) + .intValue(); + } + } + // IMPORTANT: This field can be updated by multiple threads. It follows that // its values may *not* be incremented sequentially. However, we don't care // about the actual value of the field except that from time to time the Copied: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DatePatternToSRegexUtil.java (from r2414, /logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DatePatternToRegexUtil.java) ============================================================================== --- /logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DatePatternToRegexUtil.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DatePatternToSRegexUtil.java Thu Aug 6 21:07:24 2009 @@ -21,21 +21,21 @@ * @author Ceki Gülcü * */ -public class DatePatternToRegexUtil { +public class DatePatternToSRegexUtil { final String datePattern; final int length; - DatePatternToRegexUtil(String datePattern) { + DatePatternToSRegexUtil(String datePattern) { this.datePattern = datePattern; length = datePattern.length(); } - String asRegex() { + String toSRegex() { List<SequenceToRegex4SDF> sequenceList = tokenize(); StringBuilder sb = new StringBuilder(); for (SequenceToRegex4SDF seq : sequenceList) { - sb.append(seq.toRegex()); + sb.append(seq.toSRegex()); } return sb.toString(); } Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DateTokenConverter.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DateTokenConverter.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DateTokenConverter.java Thu Aug 6 21:07:24 2009 @@ -67,8 +67,8 @@ return (o instanceof Date); } - public String asRegex() { - DatePatternToRegexUtil toRegex = new DatePatternToRegexUtil(datePattern); - return toRegex.asRegex(); + public String toSRegex() { + DatePatternToSRegexUtil toRegex = new DatePatternToSRegexUtil(datePattern); + return toRegex.toSRegex(); } } Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java Thu Aug 6 21:07:24 2009 @@ -140,17 +140,19 @@ return pattern; } - /** - * Given date, convert this instance to a regular expression - */ - public String asRegex(Date date) { + /** + * Given date, convert this instance to a slashified regular expression. A + * slashified regex, is a regex with naturally occurring forward slash + * characters replaced by back slashes. + */ + public String toSRegex(Date date) { StringBuilder buf = new StringBuilder(); Converter<Object> p = headTokenConverter; while (p != null) { if (p instanceof LiteralConverter) { - buf.append(p.convert(null)); + buf.append(slashify(p.convert(null))); } else if (p instanceof IntegerTokenConverter) { - buf.append("\\d{1,2}"); + buf.append("(\\d{1,2})"); } else if (p instanceof DateTokenConverter) { buf.append(p.convert(date)); } @@ -159,20 +161,24 @@ return buf.toString(); } + private String slashify(String in) { + return in.replace('\\', '/'); + } + /** - * Given date, convert this instance to a regular expression + * Given date, convert this instance to a slashified regular expression */ - public String asRegex() { + public String toSRegex() { StringBuilder buf = new StringBuilder(); Converter<Object> p = headTokenConverter; while (p != null) { if (p instanceof LiteralConverter) { - buf.append(p.convert(null)); + buf.append(slashify(p.convert(null))); } else if (p instanceof IntegerTokenConverter) { buf.append("\\d{1,2}"); } else if (p instanceof DateTokenConverter) { DateTokenConverter<Object> dtc = (DateTokenConverter<Object>) p; - buf.append(dtc.asRegex()); + buf.append(dtc.toSRegex()); } p = p.getNext(); } Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/SequenceToRegex4SDF.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/SequenceToRegex4SDF.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/SequenceToRegex4SDF.java Thu Aug 6 21:07:24 2009 @@ -29,7 +29,8 @@ occurrences++; } - String toRegex() { + // slashified regex + String toSRegex() { switch (c) { case 'G': return ".*"; @@ -63,6 +64,12 @@ return "(\\+|-)\\d{4}"; case '.': return "\\."; + case '\\': // slashify + String s = ""; + for(int i = 0; i < occurrences;i++) { + s += "/"; + } + return s; default: if (occurrences == 1) { return "" + c; Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP_Test.java ============================================================================== --- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP_Test.java (original) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP_Test.java Thu Aug 6 21:07:24 2009 @@ -16,6 +16,9 @@ import org.junit.Before; import org.junit.Test; +import ch.qos.logback.core.status.StatusChecker; +import ch.qos.logback.core.util.StatusPrinter; + public class SizeAndTimeBasedFNATP_Test extends ScaffoldingForRollingTests { @@ -161,6 +164,7 @@ incCurrentTime(100); tbrp2.timeBasedTriggering.setCurrentTime(currentTime); } + StatusPrinter.print(context); existenceCheck(expectedFilenameList); sortedContentCheck(randomOutputDir, runLength, prefix); } Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java ============================================================================== --- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java (original) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java Thu Aug 6 21:07:24 2009 @@ -1,13 +1,12 @@ /** - * LOGBack: the generic, reliable, fast and flexible logging framework. + * Logback: the generic, reliable, fast and flexible logging framework. * - * Copyright (C) 1999-2006, QOS.ch + * Copyright (C) 2000-2009, QOS.ch * * This library 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. */ - package ch.qos.logback.core.rolling; import static org.junit.Assert.assertTrue; Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/DatePatternToRegexTest.java ============================================================================== --- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/DatePatternToRegexTest.java (original) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/DatePatternToRegexTest.java Thu Aug 6 21:07:24 2009 @@ -46,6 +46,10 @@ doTest("yyyy-MMMM-dd", CAL_2009_08_3_NIGHT); } + @Test + public void slash() { + doTest("yyyy\\MMM\\dd", CAL_2009_08_3_NIGHT, true); + } @Test public void dot() { @@ -72,18 +76,26 @@ doTest("yyyy-MM-dd a", CAL_2009_08_3_MORNING); } - - void doTest(String datePattern, Calendar calendar) { + + void doTest(String datePattern, Calendar calendar, boolean slashified) { SimpleDateFormat sdf = new SimpleDateFormat(datePattern); DateTokenConverter dtc = makeDTC(datePattern); - verify(sdf, calendar, dtc); + verify(sdf, calendar, dtc, slashified); + } + + void doTest(String datePattern, Calendar calendar) { + doTest(datePattern, calendar, false); } + - void verify(SimpleDateFormat sdf, Calendar calendar, DateTokenConverter dtc) { + void verify(SimpleDateFormat sdf, Calendar calendar, DateTokenConverter dtc, boolean slashified) { String expected = sdf.format(calendar.getTime()); - String regex = dtc.asRegex(); + if(slashified) { + expected = expected.replace('\\', '/'); + } + String regex = dtc.toSRegex(); //System.out.println("expected="+expected); - //System.out.println(regex); + System.out.println(regex); assertTrue("[" + expected + "] does not match regex [" + regex + "]", expected.matches(regex)); } Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java ============================================================================== --- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java (original) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java Thu Aug 6 21:07:24 2009 @@ -42,7 +42,7 @@ // assertEquals("foo%", pp.convertInt(3)); pp = new FileNamePattern("%i foo", context); - + assertEquals("3 foo", pp.convertInt(3)); pp = new FileNamePattern("foo%i.xixo", context); @@ -80,7 +80,7 @@ cal.set(2003, 4, 20, 17, 55); FileNamePattern pp = new FileNamePattern("foo%d{yyyy.MM.dd}", context); - + assertEquals("foo2003.05.20", pp.convert(cal.getTime())); pp = new FileNamePattern("foo%d{yyyy.MM.dd HH:mm}", context); @@ -97,32 +97,44 @@ assertEquals("c:\\foo\\bar.3", pp.convertInt(3)); } - @Test public void objectListConverter() { Calendar cal = Calendar.getInstance(); cal.set(2003, 4, 20, 17, 55); - FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd}-%i.txt", context); - assertEquals("foo-2003.05.20-79.txt", fnp.convertMultipleArguments(cal.getTime(), 79)); + FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd}-%i.txt", + context); + assertEquals("foo-2003.05.20-79.txt", fnp.convertMultipleArguments(cal + .getTime(), 79)); } @Test public void asRegexByDate() { + Calendar cal = Calendar.getInstance(); cal.set(2003, 4, 20, 17, 55); - FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd}-%i.txt", context); - String regex = fnp.asRegex(cal.getTime()); - assertEquals("foo-2003.05.20-\\d{1,2}.txt", regex); + + { + FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd}-%i.txt", + context); + String regex = fnp.toSRegex(cal.getTime()); + assertEquals("foo-2003.05.20-\\d{1,2}.txt", regex); + } + { + FileNamePattern fnp = new FileNamePattern("\\toto\\foo-%d{yyyy\\MM\\dd}-%i.txt", + context); + String regex = fnp.toSRegex(cal.getTime()); + assertEquals("/toto/foo-2003/05/20-\\d{1,2}.txt", regex); + } } @Test public void asRegex() { Calendar cal = Calendar.getInstance(); cal.set(2003, 4, 20, 17, 55); - FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd}-%i.txt", context); - String regex = fnp.asRegex(); + FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd}-%i.txt", + context); + String regex = fnp.toSRegex(); assertEquals("foo-\\d{4}\\.\\d{2}\\.\\d{2}-\\d{1,2}.txt", regex); } - }