View Javadoc

1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.core.rolling.helper;
15  
16  import java.util.Date;
17  import java.util.HashMap;
18  import java.util.Map;
19  
20  import ch.qos.logback.core.Context;
21  import ch.qos.logback.core.pattern.Converter;
22  import ch.qos.logback.core.pattern.ConverterUtil;
23  import ch.qos.logback.core.pattern.LiteralConverter;
24  import ch.qos.logback.core.pattern.parser.Node;
25  import ch.qos.logback.core.pattern.parser.Parser;
26  import ch.qos.logback.core.pattern.parser.ScanException;
27  import ch.qos.logback.core.pattern.util.AlmostAsIsEscapeUtil;
28  import ch.qos.logback.core.spi.ContextAwareBase;
29  
30  /**
31   * After parsing file name patterns, given a number or a date, instances of this
32   * class can be used to compute a file name according to the file name pattern
33   * and the given integer or date.
34   * 
35   * @author Ceki Gülcü
36   * 
37   */
38  public class FileNamePattern extends ContextAwareBase {
39  
40    static final Map<String, String> CONVERTER_MAP = new HashMap<String, String>();
41    static {
42      CONVERTER_MAP.put(IntegerTokenConverter.CONVERTER_KEY,
43          IntegerTokenConverter.class.getName());
44      CONVERTER_MAP.put(DateTokenConverter.CONVERTER_KEY,
45          DateTokenConverter.class.getName());
46    }
47  
48    String pattern;
49    Converter<Object> headTokenConverter;
50  
51    public FileNamePattern(String patternArg, Context contextArg) {
52      // the pattern is slashified
53      setPattern(FileFilterUtil.slashify(patternArg));
54      setContext(contextArg);
55      parse();
56      ConverterUtil.startConverters(this.headTokenConverter);
57    }
58  
59    void parse() {
60      try {
61        // http://jira.qos.ch/browse/LBCORE-130
62        // we escape ')' for parsing purposes. Note that the original pattern is preserved
63        // because it is shown to the user in status messages. We don't want the escaped version
64        // to leak out.
65        String patternForParsing = escapeRightParantesis(pattern);
66        Parser<Object> p = new Parser<Object>(patternForParsing, new AlmostAsIsEscapeUtil());
67        p.setContext(context);
68        Node t = p.parse();
69        this.headTokenConverter = p.compile(t, CONVERTER_MAP);
70  
71      } catch (ScanException sce) {
72        addError("Failed to parse pattern \"" + pattern + "\".", sce);
73      }
74    }
75  
76    String escapeRightParantesis(String in) {
77      return pattern.replace(")", "\\)");
78    }
79  
80    public String toString() {
81      return pattern;
82    }
83  
84    public DateTokenConverter getDateTokenConverter() {
85      Converter p = headTokenConverter;
86  
87      while (p != null) {
88        if (p instanceof DateTokenConverter) {
89          return (DateTokenConverter) p;
90        }
91  
92        p = p.getNext();
93      }
94  
95      return null;
96    }
97  
98    public IntegerTokenConverter getIntegerTokenConverter() {
99      Converter p = headTokenConverter;
100 
101     while (p != null) {
102       if (p instanceof IntegerTokenConverter) {
103         return (IntegerTokenConverter) p;
104       }
105 
106       p = p.getNext();
107     }
108     return null;
109   }
110 
111   public String convertMultipleArguments(Object... objectList) {
112     StringBuilder buf = new StringBuilder();
113     Converter<Object> c = headTokenConverter;
114     while (c != null) {
115       if (c instanceof MonoTypedConverter) {
116         MonoTypedConverter monoTyped = (MonoTypedConverter) c;
117         for (Object o : objectList) {
118           if (monoTyped.isApplicable(o)) {
119             buf.append(c.convert(o));
120           }
121         }
122       } else {
123         buf.append(c.convert(objectList));
124       }
125       c = c.getNext();
126     }
127     return buf.toString();
128   }
129 
130   public String convert(Object o) {
131     StringBuilder buf = new StringBuilder();
132     Converter<Object> p = headTokenConverter;
133     while (p != null) {
134       buf.append(p.convert(o));
135       p = p.getNext();
136     }
137     return buf.toString();
138   }
139 
140   public String convertInt(int i) {
141     Integer integerArg = new Integer(i);
142     return convert(integerArg);
143   }
144 
145   public void setPattern(String pattern) {
146     if (pattern != null) {
147       // Trailing spaces in the pattern are assumed to be undesired.
148       this.pattern = pattern.trim();
149     }
150   }
151 
152   public String getPattern() {
153     return pattern;
154   }
155 
156   /**
157    * Given date, convert this instance to a regular expression.
158    */
159   public String toRegex(Date date) {
160     StringBuilder buf = new StringBuilder();
161     Converter<Object> p = headTokenConverter;
162     while (p != null) {
163       if (p instanceof LiteralConverter) {
164         buf.append(p.convert(null));
165       } else if (p instanceof IntegerTokenConverter) {
166         buf.append("(\\d{1,2})");
167       } else if (p instanceof DateTokenConverter) {
168         buf.append(p.convert(date));
169       }
170       p = p.getNext();
171     }
172     return buf.toString();
173   }
174 
175   /**
176    * Given date, convert this instance to a regular expression
177    */
178   public String toRegex() {
179     StringBuilder buf = new StringBuilder();
180     Converter<Object> p = headTokenConverter;
181     while (p != null) {
182       if (p instanceof LiteralConverter) {
183         buf.append(p.convert(null));
184       } else if (p instanceof IntegerTokenConverter) {
185         buf.append("\\d{1,2}");
186       } else if (p instanceof DateTokenConverter) {
187         DateTokenConverter<Object> dtc = (DateTokenConverter<Object>) p;
188         buf.append(dtc.toRegex());
189       }
190       p = p.getNext();
191     }
192     return buf.toString();
193   }
194 }