1
2
3
4
5
6
7
8
9
10
11 package ch.qos.logback.core;
12
13 import java.io.IOException;
14 import java.io.OutputStream;
15 import java.io.OutputStreamWriter;
16 import java.io.Writer;
17
18 import ch.qos.logback.core.status.ErrorStatus;
19
20
21
22
23
24
25
26
27
28
29 public class WriterAppender<E> extends AppenderBase<E> {
30
31
32
33
34
35
36
37
38
39
40
41
42 private boolean immediateFlush = true;
43
44
45
46
47
48
49 private String encoding;
50
51
52
53
54 private Writer writer;
55
56
57
58
59
60 public WriterAppender() {
61 }
62
63
64
65
66
67
68
69
70
71
72
73
74 public void setImmediateFlush(boolean value) {
75 immediateFlush = value;
76 }
77
78
79
80
81 public boolean getImmediateFlush() {
82 return immediateFlush;
83 }
84
85
86
87
88
89 public void start() {
90 int errors = 0;
91 if (this.layout == null) {
92 addStatus(new ErrorStatus("No layout set for the appender named \""
93 + name + "\".", this));
94 errors++;
95 }
96
97 if (this.writer == null) {
98 addStatus(new ErrorStatus("No writer set for the appender named \""
99 + name + "\".", this));
100 errors++;
101 }
102
103 if (errors == 0) {
104 super.start();
105 }
106 }
107
108 @Override
109 protected void append(E eventObject) {
110 if (!isStarted()) {
111 return;
112 }
113
114 subAppend(eventObject);
115 }
116
117
118
119
120
121
122
123 public synchronized void stop() {
124 closeWriter();
125 super.stop();
126 }
127
128
129
130
131 protected void closeWriter() {
132 if (this.writer != null) {
133 try {
134
135 writeFooter();
136 this.writer.close();
137 this.writer = null;
138 } catch (IOException e) {
139 addStatus(new ErrorStatus("Could not close writer for WriterAppener.",
140 this, e));
141 }
142 }
143 }
144
145
146
147
148
149
150
151
152 protected OutputStreamWriter createWriter(OutputStream os) {
153 OutputStreamWriter retval = null;
154
155 String enc = getEncoding();
156
157 try {
158 if (enc != null) {
159 retval = new OutputStreamWriter(os, enc);
160 } else {
161 retval = new OutputStreamWriter(os);
162 }
163 } catch (IOException e) {
164 addStatus(new ErrorStatus("Error initializing output writer.", this, e));
165 if (enc != null) {
166 addStatus(new ErrorStatus("Unsupported encoding?", this));
167 }
168 }
169 return retval;
170 }
171
172 public String getEncoding() {
173 return encoding;
174 }
175
176 public void setEncoding(String value) {
177 encoding = value;
178 }
179
180
181 void writeHeader() {
182 if (layout != null && (this.writer != null)) {
183 try {
184 StringBuilder sb = new StringBuilder();
185 appendIfNotNull(sb, layout.getFileHeader());
186 appendIfNotNull(sb, layout.getPresentationHeader());
187 if (sb.length() > 0) {
188 sb.append(CoreConstants.LINE_SEPARATOR);
189
190
191
192 writerWrite(sb.toString(), true);
193 }
194
195 } catch (IOException ioe) {
196 this.started = false;
197 addStatus(new ErrorStatus("Failed to write header for appender named ["
198 + name + "].", this, ioe));
199 }
200 }
201 }
202
203 private void appendIfNotNull(StringBuilder sb, String s) {
204 if (s != null) {
205 sb.append(s);
206 }
207 }
208
209 void writeFooter() {
210 if (layout != null && this.writer != null) {
211 try {
212 StringBuilder sb = new StringBuilder();
213 appendIfNotNull(sb, layout.getPresentationFooter());
214 appendIfNotNull(sb, layout.getFileFooter());
215 if (sb.length() > 0) {
216 writerWrite(sb.toString(), true);
217 }
218 } catch (IOException ioe) {
219 this.started = false;
220 addStatus(new ErrorStatus("Failed to write footer for appender named ["
221 + name + "].", this, ioe));
222 }
223 }
224 }
225
226
227
228
229
230
231
232
233
234 public synchronized void setWriter(Writer writer) {
235
236 closeWriter();
237
238 this.writer = writer;
239 writeHeader();
240 }
241
242 protected void writerWrite(String s, boolean flush) throws IOException {
243 this.writer.write(s);
244 if (flush) {
245 this.writer.flush();
246 }
247 }
248
249
250
251
252
253
254
255 protected void subAppend(E event) {
256 if (!isStarted()) {
257 return;
258 }
259
260 try {
261 writerWrite(this.layout.doLayout(event), this.immediateFlush);
262 } catch (IOException ioe) {
263
264
265 this.started = false;
266 addStatus(new ErrorStatus("IO failure in appender", this, ioe));
267 }
268 }
269
270 }