View Javadoc

1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2011, 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.encoder;
15  
16  import java.io.IOException;
17  import java.io.OutputStream;
18  import java.io.UnsupportedEncodingException;
19  import java.nio.charset.Charset;
20  
21  import ch.qos.logback.core.CoreConstants;
22  import ch.qos.logback.core.Layout;
23  
24  public class LayoutWrappingEncoder<E> extends EncoderBase<E> {
25  
26    protected Layout<E> layout;
27  
28    /**
29     * The charset to use when converting a String into bytes.
30     * <p/>
31     * By default this property has the value
32     * <code>null</null> which corresponds to
33     * the system's default charset.
34     */
35    private Charset charset;
36  
37    private boolean immediateFlush = true;
38  
39  
40    /**
41     * Sets the immediateFlush option. The default value for immediateFlush is 'true'. If set to true,
42     * the doEncode() method will immediately flush the underlying OutputStream. Although immediate flushing
43     * is safer, it also significantly degrades logging throughput.
44     *
45     * @since 1.0.3
46     */
47    public void setImmediateFlush(boolean immediateFlush) {
48      this.immediateFlush = immediateFlush;
49    }
50  
51  
52    public boolean isImmediateFlush() {
53      return immediateFlush;
54    }
55  
56  
57    public Layout<E> getLayout() {
58      return layout;
59    }
60  
61    public void setLayout(Layout<E> layout) {
62      this.layout = layout;
63    }
64  
65    public Charset getCharset() {
66      return charset;
67    }
68  
69    /**
70     * Set the charset to use when converting the string returned by the layout
71     * into bytes.
72     * <p/>
73     * By default this property has the value
74     * <code>null</null> which corresponds to
75     * the system's default charset.
76     *
77     * @param charset
78     */
79    public void setCharset(Charset charset) {
80      this.charset = charset;
81    }
82  
83    public void init(OutputStream os) throws IOException {
84      super.init(os);
85      writeHeader();
86    }
87  
88    void writeHeader() throws IOException {
89      if (layout != null && (outputStream != null)) {
90        StringBuilder sb = new StringBuilder();
91        appendIfNotNull(sb, layout.getFileHeader());
92        appendIfNotNull(sb, layout.getPresentationHeader());
93        if (sb.length() > 0) {
94          sb.append(CoreConstants.LINE_SEPARATOR);
95          // If at least one of file header or presentation header were not
96          // null, then append a line separator.
97          // This should be useful in most cases and should not hurt.
98          outputStream.write(convertToBytes(sb.toString()));
99          outputStream.flush();
100       }
101     }
102   }
103 
104   public void close() throws IOException {
105     writeFooter();
106   }
107 
108   void writeFooter() throws IOException {
109     if (layout != null && outputStream != null) {
110       StringBuilder sb = new StringBuilder();
111       appendIfNotNull(sb, layout.getPresentationFooter());
112       appendIfNotNull(sb, layout.getFileFooter());
113       if (sb.length() > 0) {
114         outputStream.write(convertToBytes(sb.toString()));
115         outputStream.flush();
116       }
117     }
118   }
119 
120   private byte[] convertToBytes(String s) {
121     if (charset == null) {
122       return s.getBytes();
123     } else {
124       try {
125         return s.getBytes(charset.name());
126       } catch (UnsupportedEncodingException e) {
127         throw new IllegalStateException(
128                 "An existing charset cannot possibly be unsupported.");
129       }
130     }
131   }
132 
133   public void doEncode(E event) throws IOException {
134     String txt = layout.doLayout(event);
135     outputStream.write(convertToBytes(txt));
136     if (immediateFlush)
137       outputStream.flush();
138   }
139 
140   public boolean isStarted() {
141     return false;
142   }
143 
144   public void start() {
145     started = true;
146   }
147 
148   public void stop() {
149     started = false;
150     if(outputStream != null) {
151       try {
152         outputStream.flush();
153       } catch (IOException e) {
154       }
155     }
156   }
157 
158   private void appendIfNotNull(StringBuilder sb, String s) {
159     if (s != null) {
160       sb.append(s);
161     }
162   }
163 
164 }