blob: 50f54424e850479928a5f8e4614fabdfcdea3564 [file] [log] [blame]
/*
* Copyright 1999,2004 The Apache Software Foundation.
*
* Licensed 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.log4j.rolling.helper;
import java.util.Date;
import org.apache.log4j.spi.ComponentBase;
/**
*
* This class helps parse file name patterns. Given a number or a date it returns
* a file name according to the file name pattern.
*
* @author Ceki Gülcü
*
*/
public class FileNamePattern extends ComponentBase {
String pattern;
int patternLength;
TokenConverter headTokenConverter;
public FileNamePattern(String pattern) {
if (pattern == null) {
throw new IllegalArgumentException(
"The argument to constrcutor cannot be null. ");
}
this.pattern = pattern;
if (pattern != null) {
patternLength = pattern.length();
// We do not want to deal with trailing spaces in the pattern.
this.pattern = this.pattern.trim();
}
parse();
}
public String toString() {
return pattern;
}
void parse() {
int lastIndex = 0;
TokenConverter tc = null;
MAIN_LOOP:
while (true) {
int i = pattern.indexOf('%', lastIndex);
if (i == -1) {
String remainingStr = pattern.substring(lastIndex);
//System.out.println("adding the identity token, I");
addTokenConverter(tc, new IdentityTokenConverter(remainingStr));
break;
} else {
// test for degenerate case where the '%' character is at the end.
if (i == (patternLength - 1)) {
String remainingStr = pattern.substring(lastIndex);
addTokenConverter(tc, new IdentityTokenConverter(remainingStr));
break;
}
//System.out.println("adding the identity token, II");
tc =
addTokenConverter(
tc, new IdentityTokenConverter(pattern.substring(lastIndex, i)));
// At this stage, we can suppose that i < patternLen -1
char nextChar = pattern.charAt(i + 1);
switch (nextChar) {
case 'i':
tc = addTokenConverter(tc, new IntegerTokenConverter());
lastIndex = i + 2;
break; // break from switch statement
case 'd':
int optionEnd = getOptionEnd(i + 2);
String option;
if (optionEnd != -1) {
option = pattern.substring(i + 3, optionEnd);
lastIndex = optionEnd + 1;
} else {
getLogger().debug("Assuming daily rotation schedule");
option = "yyyy-MM-dd";
lastIndex = i+2;
}
tc = addTokenConverter(tc, new DateTokenConverter(option));
break; // break from switch statement
case '%':
tc = addTokenConverter(tc, new IdentityTokenConverter("%"));
lastIndex = i + 2;
break;
default:
throw new IllegalArgumentException(
"The pattern[" + pattern
+ "] does not contain a valid specifer at position " + (i + 1));
}
}
}
}
/**
* Find the position of the last character of option enclosed within the '{}'
* characters inside the pattern
* */
protected int getOptionEnd(int i) {
//logger.debug("Char at "+i+" "+pattern.charAt(i));
if ((i < patternLength) && (pattern.charAt(i) == '{')) {
int end = pattern.indexOf('}', i);
if (end > i) {
return end;
} else {
return -1;
}
}
return -1;
}
TokenConverter addTokenConverter(
TokenConverter tc, TokenConverter newTokenConverter) {
if (tc == null) {
tc = headTokenConverter = newTokenConverter;
} else {
tc.next = newTokenConverter;
tc = newTokenConverter;
}
return tc;
}
public DateTokenConverter getDateTokenConverter() {
TokenConverter p = headTokenConverter;
while (p != null) {
if (p.getType() == TokenConverter.DATE) {
return (DateTokenConverter) p;
}
p = p.getNext();
}
return null;
}
public IntegerTokenConverter getIntegerTokenConverter() {
TokenConverter p = headTokenConverter;
while (p != null) {
if (p.getType() == TokenConverter.INTEGER) {
return (IntegerTokenConverter) p;
}
p = p.getNext();
}
return null;
}
public String convert(int i) {
TokenConverter p = headTokenConverter;
StringBuffer buf = new StringBuffer();
while (p != null) {
switch (p.getType()) {
case TokenConverter.IDENTITY:
buf.append(((IdentityTokenConverter) p).convert());
break;
case TokenConverter.INTEGER:
buf.append(((IntegerTokenConverter) p).convert(i));
break;
default:
getLogger().error(
"Encountered an unknown TokenConverter type for pattern [" + pattern
+ "].");
}
p = p.getNext();
}
return buf.toString();
}
public String convert(Date date) {
TokenConverter p = headTokenConverter;
StringBuffer buf = new StringBuffer();
while (p != null) {
switch (p.getType()) {
case TokenConverter.IDENTITY:
buf.append(((IdentityTokenConverter) p).convert());
break;
case TokenConverter.DATE:
buf.append(((DateTokenConverter) p).convert(date));
break;
default:
getLogger().error(
"Encountered an unknown TokenConverter type for pattern [" + pattern
+ "].");
}
p = p.getNext();
}
return buf.toString();
}
public String getPattern() {
return pattern;
}
}