Skip to content

Commit

Permalink
Control the encoding uniformly from ExtHandler and never use a null e…
Browse files Browse the repository at this point in the history
…ncoding
  • Loading branch information
dmlloyd committed Mar 13, 2020
1 parent 35e0b6b commit cd46f32
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 27 deletions.
63 changes: 61 additions & 2 deletions core/src/main/java/org/jboss/logmanager/ExtHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@

import java.io.Flushable;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.Permission;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.logging.ErrorManager;
import java.util.logging.Filter;
Expand All @@ -39,11 +41,13 @@
*/
public abstract class ExtHandler extends Handler implements AutoCloseable, Flushable {

private static final ErrorManager DEFAULT_ERROR_MANAGER = new OnlyOnceErrorManager();
private static final Permission CONTROL_PERMISSION = new LoggingPermission("control", null);

private volatile boolean autoFlush = true;
private volatile boolean enabled = true;
private volatile boolean closeChildren;
private static final ErrorManager DEFAULT_ERROR_MANAGER = new OnlyOnceErrorManager();
private volatile Charset charset = Charset.defaultCharset();

/**
* The sub-handlers for this handler. May only be updated using the {@link #handlersUpdater} atomic updater. The array
Expand Down Expand Up @@ -314,10 +318,65 @@ public void setFilter(final Filter newFilter) throws SecurityException {
super.setFilter(newFilter);
}

/**
* Set the handler's character set by name. This is roughly equivalent to calling {@link #setCharset(Charset)} with
* the results of {@link Charset#forName(String)}.
*
* @param encoding the name of the encoding
* @throws SecurityException if a security manager is installed and the caller does not have the {@code "control" LoggingPermission}
* @throws UnsupportedEncodingException if no character set could be found for the encoding name
*/
@Override
public void setEncoding(final String encoding) throws SecurityException, UnsupportedEncodingException {
try {
setCharset(Charset.forName(encoding));
} catch (IllegalArgumentException e) {
final UnsupportedEncodingException e2 = new UnsupportedEncodingException("Unable to set encoding to \"" + encoding + "\"");
e2.initCause(e);
throw e2;
}
}

/**
* Get the name of the {@linkplain #getCharset() handler's character set}.
*
* @return the handler character set name
*/
@Override
public String getEncoding() {
return getCharset().name();
}

/**
* Set the handler's character set. If not set, the handler's character set is initialized to the platform default
* character set.
*
* @param charset the character set (must not be {@code null})
* @throws SecurityException if a security manager is installed and the caller does not have the {@code "control" LoggingPermission}
*/
public void setCharset(final Charset charset) throws SecurityException {
checkAccess();
super.setEncoding(encoding);
setCharsetPrivate(charset);
}

/**
* Set the handler's character set from within this handler. If not set, the handler's character set is initialized
* to the platform default character set.
*
* @param charset the character set (must not be {@code null})
*/
protected void setCharsetPrivate(final Charset charset) throws SecurityException {
Objects.requireNonNull(charset, "charset");
this.charset = charset;
}

/**
* Get the handler's character set.
*
* @return the character set in use (not {@code null})
*/
public Charset getCharset() {
return charset;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.jboss.logmanager.formatters.Formatters;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;

import java.nio.charset.Charset;
Expand All @@ -36,7 +35,6 @@
public class OutputStreamHandler extends WriterHandler {

private OutputStream outputStream;
private Charset charset;

/**
* Construct a new instance with no formatter.
Expand Down Expand Up @@ -65,29 +63,11 @@ public OutputStreamHandler(final OutputStream outputStream, final Formatter form
setOutputStream(outputStream);
}

/**
* Get the target encoding.
*
* @return the target encoding, or {@code null} if the platform default is being used
*/
public String getEncoding() {
synchronized (outputLock) {
return super.getEncoding();
}
}

/**
* Set the target encoding.
*
* @param encoding the new encoding
* @throws SecurityException if you do not have sufficient permission to invoke this operation
* @throws java.io.UnsupportedEncodingException if the specified encoding is not supported
*/
public void setEncoding(final String encoding) throws SecurityException, UnsupportedEncodingException {
@Override
protected void setCharsetPrivate(Charset charset) throws SecurityException {
// superclass checks access
synchronized (outputLock) {
charset = encoding == null ? null : Charset.forName(encoding);
super.setEncoding(encoding);
super.setCharsetPrivate(charset);
// we only want to change the writer, not the output stream
final OutputStream outputStream = this.outputStream;
if (outputStream != null) {
Expand All @@ -96,6 +76,12 @@ public void setEncoding(final String encoding) throws SecurityException, Unsuppo
}
}

public Charset getCharset() {
synchronized (outputLock) {
return super.getCharset();
}
}

/** {@inheritDoc} Setting a writer will replace any target output stream. */
public void setWriter(final Writer writer) {
synchronized (outputLock) {
Expand Down Expand Up @@ -143,7 +129,6 @@ public void setOutputStream(final OutputStream outputStream) {
private Writer getNewWriter(OutputStream newOutputStream) {
if (newOutputStream == null) return null;
final UninterruptibleOutputStream outputStream = new UninterruptibleOutputStream(new UncloseableOutputStream(newOutputStream));
final Charset charset = this.charset;
return charset == null ? new OutputStreamWriter(outputStream) : new OutputStreamWriter(outputStream, charset);
return new OutputStreamWriter(outputStream, getCharset());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.text.DateFormatSymbols;
import java.text.Normalizer;
import java.text.Normalizer.Form;
Expand Down Expand Up @@ -462,6 +463,7 @@ public SyslogHandler(final String serverHostname, final int port, final Facility
* @throws IOException if an error occurs creating the UDP socket
*/
public SyslogHandler(final InetAddress serverAddress, final int port, final Facility facility, final SyslogType syslogType, final Protocol protocol, final String hostname) throws IOException {
setCharsetPrivate(StandardCharsets.UTF_8);
this.serverAddress = serverAddress;
this.port = port;
this.facility = facility;
Expand Down

0 comments on commit cd46f32

Please sign in to comment.