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 synchronized (destination) {
55 try {
56 TextEncoderHelper.encodeText(charsetEncoder, cachedCharBuffer, destination.getByteBuffer(), source,
57 destination);
58 } catch (final Exception ex) {
59 logEncodeTextException(ex, source, destination);
60 TextEncoderHelper.encodeTextFallBack(charset, source, destination);
61 }
62 }
63 }
64
65 private void logEncodeTextException(final Exception ex, final StringBuilder text,
66 final ByteBufferDestination destination) {
67 StatusLogger.getLogger().error("Recovering from LockingStringBuilderEncoder.encode('{}') error", text, ex);
68 }
69 }