View Javadoc

1   /**
2    * Logback: the generic, reliable, fast and flexible logging framework.
3    * 
4    * Copyright (C) 2000-2008, QOS.ch
5    * 
6    * This library is free software, you can redistribute it and/or modify it under
7    * the terms of the GNU Lesser General Public License as published by the Free
8    * Software Foundation.
9    */
10  package ch.qos.logback.core.pattern;
11  
12  import java.util.HashMap;
13  import java.util.Map;
14  
15  import ch.qos.logback.core.Context;
16  import ch.qos.logback.core.CoreConstants;
17  import ch.qos.logback.core.LayoutBase;
18  import ch.qos.logback.core.pattern.parser.Node;
19  import ch.qos.logback.core.pattern.parser.Parser;
20  import ch.qos.logback.core.pattern.parser.ScanException;
21  import ch.qos.logback.core.spi.ContextAware;
22  import ch.qos.logback.core.status.ErrorStatus;
23  import ch.qos.logback.core.status.StatusManager;
24  
25  abstract public class PatternLayoutBase<E> extends LayoutBase<E> {
26  
27    Converter<E> head;
28    String pattern;
29    protected PostCompileProcessor<E> postCompileProcessor;
30  
31    Map<String, String> instanceConverterMap = new HashMap<String, String>();
32  
33    /**
34     * Concrete implementations of this class are responsible for elaborating the
35     * mapping between pattern words and converters.
36     * 
37     * @return A map associating pattern words to the names of converter classes
38     */
39    abstract public Map<String, String> getDefaultConverterMap();
40  
41    /**
42     * Returns a map where the default converter map is merged with the map
43     * contained in the context.
44     */
45    public Map<String, String> getEffectiveConverterMap() {
46      Map<String, String> effectiveMap = new HashMap<String, String>();
47  
48      // add the least specific map fist
49      Map<String, String> defaultMap = getDefaultConverterMap();
50      if (defaultMap != null) {
51        effectiveMap.putAll(defaultMap);
52      }
53  
54      // contextMap is more specific than the default map
55      Context context = getContext();
56      if (context != null) {
57        @SuppressWarnings("unchecked")
58        Map<String, String> contextMap = (Map<String, String>) context
59            .getObject(CoreConstants.PATTERN_RULE_REGISTRY);
60        if (contextMap != null) {
61          effectiveMap.putAll(contextMap);
62        }
63      }
64      // set the most specific map last
65      effectiveMap.putAll(instanceConverterMap);
66      return effectiveMap;
67    }
68  
69    public void start() {
70      try {
71        Parser<E> p = new Parser<E>(pattern);
72        if (getContext() != null) {
73          p.setContext(getContext());
74        }
75        Node t = p.parse();
76        this.head = p.compile(t, getEffectiveConverterMap());
77        if (postCompileProcessor != null) {
78          postCompileProcessor.process(head);
79        }
80        setContextForConverters(head);
81        ConverterUtil.startConverters(this.head);
82        super.start();
83      } catch (ScanException sce) {
84        StatusManager sm = getContext().getStatusManager();
85        sm.add(new ErrorStatus("Failed to parse pattern \"" + getPattern()
86            + "\".", this, sce));
87      }
88    }
89  
90    public void setPostCompileProcessor(
91        PostCompileProcessor<E> postCompileProcessor) {
92      this.postCompileProcessor = postCompileProcessor;
93    }
94  
95    protected void setContextForConverters(Converter<E> head) {
96      Context context = getContext();
97      Converter c = head;
98      while (c != null) {
99        if (c instanceof ContextAware) {
100         ((ContextAware) c).setContext(context);
101       }
102       c = c.getNext();
103     }
104   }
105 
106   protected String writeLoopOnConverters(E event) {
107     StringBuffer buf = new StringBuffer(128);
108     Converter<E> c = head;
109     while (c != null) {
110       c.write(buf, event);
111       c = c.getNext();
112     }
113     return buf.toString();
114   }
115 
116   public String getPattern() {
117     return pattern;
118   }
119 
120   public void setPattern(String pattern) {
121     this.pattern = pattern;
122   }
123 
124   public String toString() {
125     return this.getClass().getName() + "(" + getPattern() + ")";
126   }
127 
128   public Map<String, String> getInstanceConverterMap() {
129     return instanceConverterMap;
130   }
131 }