View Javadoc

1   /**
2    * LOGBack: the reliable, fast and flexible logging library for Java.
3    * 
4    * Copyright (C) 1999-2006, 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.parser;
11  
12  import java.util.Map;
13  
14  import ch.qos.logback.core.pattern.CompositeConverter;
15  import ch.qos.logback.core.pattern.Converter;
16  import ch.qos.logback.core.pattern.DynamicConverter;
17  import ch.qos.logback.core.pattern.LiteralConverter;
18  import ch.qos.logback.core.spi.ContextAwareBase;
19  import ch.qos.logback.core.status.ErrorStatus;
20  import ch.qos.logback.core.util.OptionHelper;
21  
22  class Compiler<E> extends ContextAwareBase {
23  
24    Converter<E> head;
25    Converter<E> tail;
26    final Node top;
27    final Map converterMap;
28  
29    Compiler(final Node top, final Map converterMap) {
30      this.top = top;
31      this.converterMap = converterMap;
32    }
33  
34    Converter<E> compile() {
35      head = tail = null;
36      for (Node n = top; n != null; n = n.next) {
37        switch (n.type) {
38        case Node.LITERAL:
39          addToList(new LiteralConverter<E>((String) n.getValue()));
40          break;
41        case Node.COMPOSITE:
42          CompositeNode cn = (CompositeNode) n;
43          CompositeConverter<E> compositeConverter = new CompositeConverter<E>();
44          compositeConverter.setFormattingInfo(cn.getFormatInfo());
45          Compiler<E> childCompiler = new Compiler<E>(cn.getChildNode(),
46              converterMap);
47          childCompiler.setContext(context);
48          Converter<E> childConverter = childCompiler.compile();
49          compositeConverter.setChildConverter(childConverter);
50          addToList(compositeConverter);
51          break;
52        case Node.KEYWORD:
53          KeywordNode kn = (KeywordNode) n;
54          DynamicConverter<E> dynaConverter = createConverter(kn);
55          if (dynaConverter != null) {
56            dynaConverter.setFormattingInfo(kn.getFormatInfo());
57            dynaConverter.setOptionList(kn.getOptions());
58            addToList(dynaConverter);
59          } else {
60            // if the appropriate dynaconverter cannot be found, then replace
61            // it with a dummy LiteralConverter indicating an error.
62            Converter<E> errConveter = new LiteralConverter<E>("%PARSER_ERROR_"
63                + kn.getValue());
64            addStatus(new ErrorStatus("[" + kn.getValue()
65                + "] is not a valid conversion word", this));
66            addToList(errConveter);
67          }
68  
69        }
70      }
71      return head;
72    }
73  
74    private void addToList(Converter<E> c) {
75      if (head == null) {
76        head = tail = c;
77      } else {
78        tail.setNext(c);
79        tail = c;
80      }
81    }
82  
83    /**
84     * Attempt to create a converter using the information found in
85     * 'converterMap'.
86     * 
87     * @param kn
88     * @return
89     */
90    @SuppressWarnings("unchecked")
91    DynamicConverter<E> createConverter(KeywordNode kn) {
92      String keyword = (String) kn.getValue();
93      String converterClassStr = (String) converterMap.get(keyword);
94  
95      if (converterClassStr != null) {
96        try {
97          return (DynamicConverter) OptionHelper.instantiateByClassName(
98              converterClassStr, DynamicConverter.class, context);
99        } catch (Exception e) {
100         addError("Failed to instantiate converter class [" + converterClassStr
101             + "]", e);
102         return null;
103       }
104     } else {
105       addError("There is no conversion class registered for conversion word ["
106           + keyword + "]");
107       return null;
108     }
109   }
110 
111   // public void setStatusManager(StatusManager statusManager) {
112   // this.statusManager = statusManager;
113   // }
114   //  
115   // void addStatus(Status status) {
116   // if(statusManager != null) {
117   // statusManager.add(status);
118   // }
119   // }
120 }