1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.layout;
18
19 import org.apache.logging.log4j.core.util.Constants;
20 import org.apache.logging.log4j.status.StatusLogger;
21
22 import java.nio.CharBuffer;
23 import java.nio.charset.Charset;
24 import java.nio.charset.CharsetEncoder;
25 import java.nio.charset.CodingErrorAction;
26 import java.util.Objects;
27
28
29
30
31 public class LockingStringBuilderEncoder implements Encoder<StringBuilder> {
32
33 private final Charset charset;
34 private final CharsetEncoder charsetEncoder;
35 private final CharBuffer cachedCharBuffer;
36
37 public LockingStringBuilderEncoder(final Charset charset) {
38 this(charset, Constants.ENCODER_CHAR_BUFFER_SIZE);
39 }
40
41 public LockingStringBuilderEncoder(final Charset charset, final int charBufferSize) {
42 this.charset = Objects.requireNonNull(charset, "charset");
43 this.charsetEncoder = charset.newEncoder().onMalformedInput(CodingErrorAction.REPLACE)
44 .onUnmappableCharacter(CodingErrorAction.REPLACE);
45 this.cachedCharBuffer = CharBuffer.wrap(new char[charBufferSize]);
46 }
47
48 private CharBuffer getCharBuffer() {
49 return cachedCharBuffer;
50 }
51
52 @Override
53 public void encode(final StringBuilder source, final ByteBufferDestination destination) {
54 try {
55
56 synchronized (destination) {
57 TextEncoderHelper.encodeText(charsetEncoder, cachedCharBuffer, destination.getByteBuffer(), source,
58 destination);
59 }
60 } catch (final Exception ex) {
61 logEncodeTextException(ex, source, destination);
62 TextEncoderHelper.encodeTextFallBack(charset, source, destination);
63 }
64
65 }
66
67 private void logEncodeTextException(final Exception ex, final StringBuilder text,
68 final ByteBufferDestination destination) {
69 StatusLogger.getLogger().error("Recovering from LockingStringBuilderEncoder.encode('{}') error", text, ex);
70 }
71 }