You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2014/09/15 01:26:57 UTC
[08/21] git commit: Move type converters to own package.
Move type converters to own package.
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/d33cda77
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/d33cda77
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/d33cda77
Branch: refs/heads/master
Commit: d33cda778dba34cffdb2a217c03d58eb0e6fd7d5
Parents: 420fa79
Author: Matt Sicker <ma...@apache.org>
Authored: Sun Sep 14 13:02:57 2014 -0500
Committer: Matt Sicker <ma...@apache.org>
Committed: Sun Sep 14 13:02:57 2014 -0500
----------------------------------------------------------------------
.../core/config/AbstractConfiguration.java | 34 +-
.../config/plugins/convert/TypeConverter.java | 38 ++
.../config/plugins/convert/TypeConverters.java | 447 +++++++++++++++++++
.../core/config/plugins/util/TypeConverter.java | 38 --
.../config/plugins/util/TypeConverters.java | 447 -------------------
.../plugins/visitors/AbstractPluginVisitor.java | 2 +-
.../plugins/convert/TypeConvertersTest.java | 202 +++++++++
.../config/plugins/util/TypeConvertersTest.java | 203 ---------
8 files changed, 705 insertions(+), 706 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d33cda77/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
index 9d9129c..208f97a 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
@@ -16,6 +16,21 @@
*/
package org.apache.logging.log4j.core.config;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
@@ -45,21 +60,6 @@ import org.apache.logging.log4j.core.util.NameUtil;
import org.apache.logging.log4j.spi.LoggerContextFactory;
import org.apache.logging.log4j.util.PropertiesUtil;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-
/**
* The base Configuration. Many configuration implementations will extend this class.
*/
@@ -699,7 +699,7 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement
* {@link org.apache.logging.log4j.core.config.plugins.PluginFactory}, and each parameter should be annotated with
* an appropriate plugin annotation depending on what that parameter describes. Parameters annotated with
* {@link org.apache.logging.log4j.core.config.plugins.PluginAttribute} must be a type that can be converted from
- * a string using one of the {@link org.apache.logging.log4j.core.config.plugins.util.TypeConverter TypeConverters}.
+ * a string using one of the {@link org.apache.logging.log4j.core.config.plugins.convert.TypeConverter TypeConverters}.
* Parameters with {@link org.apache.logging.log4j.core.config.plugins.PluginElement} may be any plugin class or an
* array of a plugin class. Collections and Maps are currently not supported, although the factory method that is
* called can create these from an array.
@@ -727,7 +727,7 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement
* @return the created plugin object or {@code null} if there was an error setting it up.
* @see org.apache.logging.log4j.core.config.plugins.util.PluginBuilder
* @see org.apache.logging.log4j.core.config.plugins.visitors.PluginVisitor
- * @see org.apache.logging.log4j.core.config.plugins.util.TypeConverter
+ * @see org.apache.logging.log4j.core.config.plugins.convert.TypeConverter
*/
private <T> Object createPluginObject(final PluginType<T> type, final Node node, final LogEvent event)
{
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d33cda77/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConverter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConverter.java
new file mode 100644
index 0000000..be8a723
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConverter.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.logging.log4j.core.config.plugins.convert;
+
+/**
+ * Interface for doing automatic String conversion to a specific type.
+ *
+ * @param <T>
+ * Converts Strings into the given type {@code T}.
+ */
+public interface TypeConverter<T> {
+
+ /**
+ * Converts a String to a given type.
+ *
+ * @param s
+ * the String to convert. Cannot be {@code null}.
+ * @return the converted object.
+ * @throws Exception
+ * thrown when a conversion error occurs
+ */
+ T convert(String s) throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d33cda77/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.java
new file mode 100644
index 0000000..c693fa2
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.java
@@ -0,0 +1,447 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.logging.log4j.core.config.plugins.convert;
+
+import java.io.File;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.security.Provider;
+import java.security.Security;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Pattern;
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.appender.ConsoleAppender;
+import org.apache.logging.log4j.core.layout.GelfLayout;
+import org.apache.logging.log4j.core.layout.HtmlLayout;
+import org.apache.logging.log4j.core.net.Facility;
+import org.apache.logging.log4j.core.net.Protocol;
+import org.apache.logging.log4j.core.util.Assert;
+import org.apache.logging.log4j.core.util.Loader;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.EnglishEnums;
+
+/**
+ * Collection of basic TypeConverter implementations. May be used to register additional TypeConverters or find
+ * registered TypeConverters.
+ */
+public final class TypeConverters {
+
+ // TODO: this could probably be combined with the usual plugin architecture instead
+
+ /**
+ * Parses a {@link String} into a {@link BigDecimal}.
+ */
+ public static class BigDecimalConverter implements TypeConverter<BigDecimal> {
+ @Override
+ public BigDecimal convert(final String s) {
+ return new BigDecimal(s);
+ }
+ }
+
+ /**
+ * Parses a {@link String} into a {@link BigInteger}.
+ */
+ public static class BigIntegerConverter implements TypeConverter<BigInteger> {
+ @Override
+ public BigInteger convert(final String s) {
+ return new BigInteger(s);
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@link Boolean}.
+ */
+ public static class BooleanConverter implements TypeConverter<Boolean> {
+ @Override
+ public Boolean convert(final String s) {
+ return Boolean.valueOf(s);
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@code byte[]}.
+ *
+ * The supported formats are:
+ * <ul>
+ * <li>0x0123456789ABCDEF</li>
+ * <li>Base64:ABase64String</li>
+ * <li>String</li>
+ * </ul>
+ */
+ public static class ByteArrayConverter implements TypeConverter<byte[]> {
+
+ private static final String PREFIX_0x = "0x";
+ private static final String PREFIX_BASE64 = "Base64:";
+
+ @Override
+ public byte[] convert(final String value) {
+ byte[] bytes;
+ if (value == null || value.isEmpty()) {
+ bytes = new byte[0];
+ } else if (value.startsWith(PREFIX_BASE64)) {
+ final String lexicalXSDBase64Binary = value.substring(PREFIX_BASE64.length());
+ bytes = DatatypeConverter.parseBase64Binary(lexicalXSDBase64Binary);
+ } else if (value.startsWith(PREFIX_0x)) {
+ final String lexicalXSDHexBinary = value.substring(PREFIX_0x.length());
+ bytes = DatatypeConverter.parseHexBinary(lexicalXSDHexBinary);
+ } else {
+ bytes = value.getBytes(Charset.defaultCharset());
+ }
+ return bytes;
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@link Byte}.
+ */
+ public static class ByteConverter implements TypeConverter<Byte> {
+ @Override
+ public Byte convert(final String s) {
+ return Byte.valueOf(s);
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@link Character}.
+ */
+ public static class CharacterConverter implements TypeConverter<Character> {
+ @Override
+ public Character convert(final String s) {
+ if (s.length() != 1) {
+ throw new IllegalArgumentException("Character string must be of length 1: " + s);
+ }
+ return Character.valueOf(s.toCharArray()[0]);
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@code char[]}.
+ */
+ public static class CharArrayConverter implements TypeConverter<char[]> {
+ @Override
+ public char[] convert(final String s) {
+ return s.toCharArray();
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@link Charset}.
+ */
+ public static class CharsetConverter implements TypeConverter<Charset> {
+ @Override
+ public Charset convert(final String s) {
+ return Charset.forName(s);
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@link Class}.
+ */
+ public static class ClassConverter implements TypeConverter<Class<?>> {
+ @Override
+ public Class<?> convert(final String s) throws ClassNotFoundException {
+ return Loader.loadClass(s);
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@link Double}.
+ */
+ public static class DoubleConverter implements TypeConverter<Double> {
+ @Override
+ public Double convert(final String s) {
+ return Double.valueOf(s);
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@link Enum}. Returns {@code null} for invalid enum names.
+ *
+ * @param <E>
+ * the enum class to parse.
+ */
+ public static class EnumConverter<E extends Enum<E>> implements TypeConverter<E> {
+ private final Class<E> clazz;
+
+ private EnumConverter(final Class<E> clazz) {
+ this.clazz = clazz;
+ }
+
+ @Override
+ public E convert(final String s) {
+ return EnglishEnums.valueOf(clazz, s);
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@link File}.
+ */
+ public static class FileConverter implements TypeConverter<File> {
+ @Override
+ public File convert(final String s) {
+ return new File(s);
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@link Float}.
+ */
+ public static class FloatConverter implements TypeConverter<Float> {
+ @Override
+ public Float convert(final String s) {
+ return Float.valueOf(s);
+ }
+ }
+
+ private static final class Holder {
+ private static final TypeConverters INSTANCE = new TypeConverters();
+ }
+
+ /**
+ * Converts a {@link String} into a {@link Integer}.
+ */
+ public static class IntegerConverter implements TypeConverter<Integer> {
+ @Override
+ public Integer convert(final String s) {
+ return Integer.valueOf(s);
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a Log4j {@link Level}. Returns {@code null} for invalid level names.
+ */
+ public static class LevelConverter implements TypeConverter<Level> {
+ @Override
+ public Level convert(final String s) {
+ return Level.valueOf(s);
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@link Long}.
+ */
+ public static class LongConverter implements TypeConverter<Long> {
+ @Override
+ public Long convert(final String s) {
+ return Long.valueOf(s);
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@link Pattern}.
+ */
+ public static class PatternConverter implements TypeConverter<Pattern> {
+ @Override
+ public Pattern convert(final String s) {
+ return Pattern.compile(s);
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@link Pattern}.
+ */
+ public static class SecurityProviderConverter implements TypeConverter<Provider> {
+ @Override
+ public Provider convert(final String s) {
+ return Security.getProvider(s);
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@link Short}.
+ */
+ public static class ShortConverter implements TypeConverter<Short> {
+ @Override
+ public Short convert(final String s) {
+ return Short.valueOf(s);
+ }
+ }
+
+ /**
+ * Returns the given {@link String}, no conversion takes place.
+ */
+ public static class StringConverter implements TypeConverter<String> {
+ @Override
+ public String convert(final String s) {
+ return s;
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@link URI}.
+ */
+ public static class UriConverter implements TypeConverter<URI> {
+ @Override
+ public URI convert(final String s) throws URISyntaxException {
+ return new URI(s);
+ }
+ }
+
+ /**
+ * Converts a {@link String} into a {@link URL}.
+ */
+ public static class UrlConverter implements TypeConverter<URL> {
+ @Override
+ public URL convert(final String s) throws MalformedURLException {
+ return new URL(s);
+ }
+ }
+
+ /**
+ * Converts a String to a given class if a TypeConverter is available for that class. Falls back to the provided
+ * default value if the conversion is unsuccessful. However, if the default value is <em>also</em> invalid, then
+ * {@code null} is returned (along with a nasty status log message).
+ *
+ * @param s
+ * the string to convert
+ * @param clazz
+ * the class to try to convert the string to
+ * @param defaultValue
+ * the fallback object to use if the conversion is unsuccessful
+ * @return the converted object which may be {@code null} if the string is invalid for the given type
+ * @throws NullPointerException
+ * if {@code clazz} is {@code null}
+ * @throws IllegalArgumentException
+ * if no TypeConverter exists for the given class
+ */
+ public static Object convert(final String s, final Class<?> clazz, final Object defaultValue) {
+ final TypeConverter<?> converter = findTypeConverter(Assert.requireNonNull(clazz,
+ "No class specified to convert to."));
+ if (converter == null) {
+ throw new IllegalArgumentException("No type converter found for class: " + clazz.getName());
+ }
+ if (s == null) {
+ // don't debug print here, resulting output is hard to understand
+ // LOGGER.debug("Null string given to convert. Using default [{}].", defaultValue);
+ return parseDefaultValue(converter, defaultValue);
+ }
+ try {
+ return converter.convert(s);
+ } catch (final Exception e) {
+ LOGGER.warn("Error while converting string [{}] to type [{}]. Using default value [{}].", s, clazz,
+ defaultValue, e);
+ return parseDefaultValue(converter, defaultValue);
+ }
+ }
+
+ /**
+ * Locates a TypeConverter for a specified class.
+ *
+ * @param clazz
+ * the class to get a TypeConverter for
+ * @return the associated TypeConverter for that class or {@code null} if none could be found
+ */
+ public static TypeConverter<?> findTypeConverter(final Class<?> clazz) {
+ // TODO: what to do if there's no converter?
+ // supplementary idea: automatically add type converters for enums using EnglishEnums
+ // Idea 1: use reflection to see if the class has a static "valueOf" method and use that
+ // Idea 2: reflect on class's declared methods to see if any methods look suitable (probably too complex)
+ return Holder.INSTANCE.registry.get(clazz);
+ }
+
+ private static Object parseDefaultValue(final TypeConverter<?> converter, final Object defaultValue) {
+ if (defaultValue == null) {
+ return null;
+ }
+ if (!(defaultValue instanceof String)) {
+ return defaultValue;
+ }
+ try {
+ return converter.convert((String) defaultValue);
+ } catch (final Exception e) {
+ LOGGER.debug("Can't parse default value [{}] for type [{}].", defaultValue, converter.getClass(), e);
+ return null;
+ }
+ }
+
+ /**
+ * Registers a TypeConverter for a specified class. This will overwrite any existing TypeConverter that may be
+ * registered for the class.
+ *
+ * @param clazz
+ * the class to register the TypeConverter for
+ * @param converter
+ * the TypeConverter to register
+ */
+ public static void registerTypeConverter(final Class<?> clazz, final TypeConverter<?> converter) {
+ Holder.INSTANCE.registry.put(clazz, converter);
+ }
+
+ private static final Logger LOGGER = StatusLogger.getLogger();
+
+ private final Map<Class<?>, TypeConverter<?>> registry = new ConcurrentHashMap<Class<?>, TypeConverter<?>>();
+
+ /**
+ * Constructs default TypeConverter registry. Used solely by singleton instance.
+ */
+ private TypeConverters() {
+ // Primitive wrappers
+ registry.put(Boolean.class, new BooleanConverter());
+ registry.put(Byte.class, new ByteConverter());
+ registry.put(Character.class, new CharacterConverter());
+ registry.put(Double.class, new DoubleConverter());
+ registry.put(Float.class, new FloatConverter());
+ registry.put(Integer.class, new IntegerConverter());
+ registry.put(Long.class, new LongConverter());
+ registry.put(Short.class, new ShortConverter());
+ // Primitives
+ registry.put(boolean.class, registry.get(Boolean.class));
+ registry.put(byte.class, new ByteConverter());
+ registry.put(char[].class, new CharArrayConverter());
+ registry.put(double.class, registry.get(Double.class));
+ registry.put(float.class, registry.get(Float.class));
+ registry.put(int.class, registry.get(Integer.class));
+ registry.put(long.class, registry.get(Long.class));
+ registry.put(short.class, registry.get(Short.class));
+ // Primitive arrays
+ registry.put(byte[].class, new ByteArrayConverter());
+ registry.put(char.class, new CharacterConverter());
+ // Numbers
+ registry.put(BigInteger.class, new BigIntegerConverter());
+ registry.put(BigDecimal.class, new BigDecimalConverter());
+ // JRE
+ registry.put(String.class, new StringConverter());
+ registry.put(Charset.class, new CharsetConverter());
+ registry.put(File.class, new FileConverter());
+ registry.put(URL.class, new UrlConverter());
+ registry.put(URI.class, new UriConverter());
+ registry.put(Class.class, new ClassConverter());
+ registry.put(Pattern.class, new PatternConverter());
+ registry.put(Provider.class, new SecurityProviderConverter());
+ // Log4J
+ registry.put(Level.class, new LevelConverter());
+ registry.put(Filter.Result.class, new EnumConverter<Filter.Result>(Filter.Result.class));
+ registry.put(Facility.class, new EnumConverter<Facility>(Facility.class));
+ registry.put(Protocol.class, new EnumConverter<Protocol>(Protocol.class));
+ registry.put(GelfLayout.CompressionType.class, new EnumConverter<GelfLayout.CompressionType>(
+ GelfLayout.CompressionType.class));
+ registry.put(HtmlLayout.FontSize.class, new EnumConverter<HtmlLayout.FontSize>(HtmlLayout.FontSize.class));
+ registry.put(ConsoleAppender.Target.class, new EnumConverter<ConsoleAppender.Target>(
+ ConsoleAppender.Target.class));
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d33cda77/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/TypeConverter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/TypeConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/TypeConverter.java
deleted file mode 100644
index fc4ca56..0000000
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/TypeConverter.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.logging.log4j.core.config.plugins.util;
-
-/**
- * Interface for doing automatic String conversion to a specific type.
- *
- * @param <T>
- * Converts Strings into the given type {@code T}.
- */
-public interface TypeConverter<T> {
-
- /**
- * Converts a String to a given type.
- *
- * @param s
- * the String to convert. Cannot be {@code null}.
- * @return the converted object.
- * @throws Exception
- * thrown when a conversion error occurs
- */
- T convert(String s) throws Exception;
-}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d33cda77/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/TypeConverters.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/TypeConverters.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/TypeConverters.java
deleted file mode 100644
index 7bf1ec0..0000000
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/TypeConverters.java
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.logging.log4j.core.config.plugins.util;
-
-import java.io.File;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.charset.Charset;
-import java.security.Provider;
-import java.security.Security;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.regex.Pattern;
-import javax.xml.bind.DatatypeConverter;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.Filter;
-import org.apache.logging.log4j.core.appender.ConsoleAppender;
-import org.apache.logging.log4j.core.layout.GelfLayout;
-import org.apache.logging.log4j.core.layout.HtmlLayout;
-import org.apache.logging.log4j.core.net.Facility;
-import org.apache.logging.log4j.core.net.Protocol;
-import org.apache.logging.log4j.core.util.Assert;
-import org.apache.logging.log4j.core.util.Loader;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.apache.logging.log4j.util.EnglishEnums;
-
-/**
- * Collection of basic TypeConverter implementations. May be used to register additional TypeConverters or find
- * registered TypeConverters.
- */
-public final class TypeConverters {
-
- // TODO: this could probably be combined with the usual plugin architecture instead
-
- /**
- * Parses a {@link String} into a {@link BigDecimal}.
- */
- public static class BigDecimalConverter implements TypeConverter<BigDecimal> {
- @Override
- public BigDecimal convert(final String s) {
- return new BigDecimal(s);
- }
- }
-
- /**
- * Parses a {@link String} into a {@link BigInteger}.
- */
- public static class BigIntegerConverter implements TypeConverter<BigInteger> {
- @Override
- public BigInteger convert(final String s) {
- return new BigInteger(s);
- }
- }
-
- /**
- * Converts a {@link String} into a {@link Boolean}.
- */
- public static class BooleanConverter implements TypeConverter<Boolean> {
- @Override
- public Boolean convert(final String s) {
- return Boolean.valueOf(s);
- }
- }
-
- /**
- * Converts a {@link String} into a {@code byte[]}.
- *
- * The supported formats are:
- * <ul>
- * <li>0x0123456789ABCDEF</li>
- * <li>Base64:ABase64String</li>
- * <li>String</li>
- * </ul>
- */
- public static class ByteArrayConverter implements TypeConverter<byte[]> {
-
- private static final String PREFIX_0x = "0x";
- private static final String PREFIX_BASE64 = "Base64:";
-
- @Override
- public byte[] convert(final String value) {
- byte[] bytes;
- if (value == null || value.isEmpty()) {
- bytes = new byte[0];
- } else if (value.startsWith(PREFIX_BASE64)) {
- final String lexicalXSDBase64Binary = value.substring(PREFIX_BASE64.length());
- bytes = DatatypeConverter.parseBase64Binary(lexicalXSDBase64Binary);
- } else if (value.startsWith(PREFIX_0x)) {
- final String lexicalXSDHexBinary = value.substring(PREFIX_0x.length());
- bytes = DatatypeConverter.parseHexBinary(lexicalXSDHexBinary);
- } else {
- bytes = value.getBytes(Charset.defaultCharset());
- }
- return bytes;
- }
- }
-
- /**
- * Converts a {@link String} into a {@link Byte}.
- */
- public static class ByteConverter implements TypeConverter<Byte> {
- @Override
- public Byte convert(final String s) {
- return Byte.valueOf(s);
- }
- }
-
- /**
- * Converts a {@link String} into a {@link Character}.
- */
- public static class CharacterConverter implements TypeConverter<Character> {
- @Override
- public Character convert(final String s) {
- if (s.length() != 1) {
- throw new IllegalArgumentException("Character string must be of length 1: " + s);
- }
- return Character.valueOf(s.toCharArray()[0]);
- }
- }
-
- /**
- * Converts a {@link String} into a {@code char[]}.
- */
- public static class CharArrayConverter implements TypeConverter<char[]> {
- @Override
- public char[] convert(final String s) {
- return s.toCharArray();
- }
- }
-
- /**
- * Converts a {@link String} into a {@link Charset}.
- */
- public static class CharsetConverter implements TypeConverter<Charset> {
- @Override
- public Charset convert(final String s) {
- return Charset.forName(s);
- }
- }
-
- /**
- * Converts a {@link String} into a {@link Class}.
- */
- public static class ClassConverter implements TypeConverter<Class<?>> {
- @Override
- public Class<?> convert(final String s) throws ClassNotFoundException {
- return Loader.loadClass(s);
- }
- }
-
- /**
- * Converts a {@link String} into a {@link Double}.
- */
- public static class DoubleConverter implements TypeConverter<Double> {
- @Override
- public Double convert(final String s) {
- return Double.valueOf(s);
- }
- }
-
- /**
- * Converts a {@link String} into a {@link Enum}. Returns {@code null} for invalid enum names.
- *
- * @param <E>
- * the enum class to parse.
- */
- public static class EnumConverter<E extends Enum<E>> implements TypeConverter<E> {
- private final Class<E> clazz;
-
- private EnumConverter(final Class<E> clazz) {
- this.clazz = clazz;
- }
-
- @Override
- public E convert(final String s) {
- return EnglishEnums.valueOf(clazz, s);
- }
- }
-
- /**
- * Converts a {@link String} into a {@link File}.
- */
- public static class FileConverter implements TypeConverter<File> {
- @Override
- public File convert(final String s) {
- return new File(s);
- }
- }
-
- /**
- * Converts a {@link String} into a {@link Float}.
- */
- public static class FloatConverter implements TypeConverter<Float> {
- @Override
- public Float convert(final String s) {
- return Float.valueOf(s);
- }
- }
-
- private static final class Holder {
- private static final TypeConverters INSTANCE = new TypeConverters();
- }
-
- /**
- * Converts a {@link String} into a {@link Integer}.
- */
- public static class IntegerConverter implements TypeConverter<Integer> {
- @Override
- public Integer convert(final String s) {
- return Integer.valueOf(s);
- }
- }
-
- /**
- * Converts a {@link String} into a Log4j {@link Level}. Returns {@code null} for invalid level names.
- */
- public static class LevelConverter implements TypeConverter<Level> {
- @Override
- public Level convert(final String s) {
- return Level.valueOf(s);
- }
- }
-
- /**
- * Converts a {@link String} into a {@link Long}.
- */
- public static class LongConverter implements TypeConverter<Long> {
- @Override
- public Long convert(final String s) {
- return Long.valueOf(s);
- }
- }
-
- /**
- * Converts a {@link String} into a {@link Pattern}.
- */
- public static class PatternConverter implements TypeConverter<Pattern> {
- @Override
- public Pattern convert(final String s) {
- return Pattern.compile(s);
- }
- }
-
- /**
- * Converts a {@link String} into a {@link Pattern}.
- */
- public static class SecurityProviderConverter implements TypeConverter<Provider> {
- @Override
- public Provider convert(final String s) {
- return Security.getProvider(s);
- }
- }
-
- /**
- * Converts a {@link String} into a {@link Short}.
- */
- public static class ShortConverter implements TypeConverter<Short> {
- @Override
- public Short convert(final String s) {
- return Short.valueOf(s);
- }
- }
-
- /**
- * Returns the given {@link String}, no conversion takes place.
- */
- public static class StringConverter implements TypeConverter<String> {
- @Override
- public String convert(final String s) {
- return s;
- }
- }
-
- /**
- * Converts a {@link String} into a {@link URI}.
- */
- public static class UriConverter implements TypeConverter<URI> {
- @Override
- public URI convert(final String s) throws URISyntaxException {
- return new URI(s);
- }
- }
-
- /**
- * Converts a {@link String} into a {@link URL}.
- */
- public static class UrlConverter implements TypeConverter<URL> {
- @Override
- public URL convert(final String s) throws MalformedURLException {
- return new URL(s);
- }
- }
-
- /**
- * Converts a String to a given class if a TypeConverter is available for that class. Falls back to the provided
- * default value if the conversion is unsuccessful. However, if the default value is <em>also</em> invalid, then
- * {@code null} is returned (along with a nasty status log message).
- *
- * @param s
- * the string to convert
- * @param clazz
- * the class to try to convert the string to
- * @param defaultValue
- * the fallback object to use if the conversion is unsuccessful
- * @return the converted object which may be {@code null} if the string is invalid for the given type
- * @throws NullPointerException
- * if {@code clazz} is {@code null}
- * @throws IllegalArgumentException
- * if no TypeConverter exists for the given class
- */
- public static Object convert(final String s, final Class<?> clazz, final Object defaultValue) {
- final TypeConverter<?> converter = findTypeConverter(Assert.requireNonNull(clazz,
- "No class specified to convert to."));
- if (converter == null) {
- throw new IllegalArgumentException("No type converter found for class: " + clazz.getName());
- }
- if (s == null) {
- // don't debug print here, resulting output is hard to understand
- // LOGGER.debug("Null string given to convert. Using default [{}].", defaultValue);
- return parseDefaultValue(converter, defaultValue);
- }
- try {
- return converter.convert(s);
- } catch (final Exception e) {
- LOGGER.warn("Error while converting string [{}] to type [{}]. Using default value [{}].", s, clazz,
- defaultValue, e);
- return parseDefaultValue(converter, defaultValue);
- }
- }
-
- /**
- * Locates a TypeConverter for a specified class.
- *
- * @param clazz
- * the class to get a TypeConverter for
- * @return the associated TypeConverter for that class or {@code null} if none could be found
- */
- public static TypeConverter<?> findTypeConverter(final Class<?> clazz) {
- // TODO: what to do if there's no converter?
- // supplementary idea: automatically add type converters for enums using EnglishEnums
- // Idea 1: use reflection to see if the class has a static "valueOf" method and use that
- // Idea 2: reflect on class's declared methods to see if any methods look suitable (probably too complex)
- return Holder.INSTANCE.registry.get(clazz);
- }
-
- private static Object parseDefaultValue(final TypeConverter<?> converter, final Object defaultValue) {
- if (defaultValue == null) {
- return null;
- }
- if (!(defaultValue instanceof String)) {
- return defaultValue;
- }
- try {
- return converter.convert((String) defaultValue);
- } catch (final Exception e) {
- LOGGER.debug("Can't parse default value [{}] for type [{}].", defaultValue, converter.getClass(), e);
- return null;
- }
- }
-
- /**
- * Registers a TypeConverter for a specified class. This will overwrite any existing TypeConverter that may be
- * registered for the class.
- *
- * @param clazz
- * the class to register the TypeConverter for
- * @param converter
- * the TypeConverter to register
- */
- public static void registerTypeConverter(final Class<?> clazz, final TypeConverter<?> converter) {
- Holder.INSTANCE.registry.put(clazz, converter);
- }
-
- private static final Logger LOGGER = StatusLogger.getLogger();
-
- private final Map<Class<?>, TypeConverter<?>> registry = new ConcurrentHashMap<Class<?>, TypeConverter<?>>();
-
- /**
- * Constructs default TypeConverter registry. Used solely by singleton instance.
- */
- private TypeConverters() {
- // Primitive wrappers
- registry.put(Boolean.class, new BooleanConverter());
- registry.put(Byte.class, new ByteConverter());
- registry.put(Character.class, new CharacterConverter());
- registry.put(Double.class, new DoubleConverter());
- registry.put(Float.class, new FloatConverter());
- registry.put(Integer.class, new IntegerConverter());
- registry.put(Long.class, new LongConverter());
- registry.put(Short.class, new ShortConverter());
- // Primitives
- registry.put(boolean.class, registry.get(Boolean.class));
- registry.put(byte.class, new ByteConverter());
- registry.put(char[].class, new CharArrayConverter());
- registry.put(double.class, registry.get(Double.class));
- registry.put(float.class, registry.get(Float.class));
- registry.put(int.class, registry.get(Integer.class));
- registry.put(long.class, registry.get(Long.class));
- registry.put(short.class, registry.get(Short.class));
- // Primitive arrays
- registry.put(byte[].class, new ByteArrayConverter());
- registry.put(char.class, new CharacterConverter());
- // Numbers
- registry.put(BigInteger.class, new BigIntegerConverter());
- registry.put(BigDecimal.class, new BigDecimalConverter());
- // JRE
- registry.put(String.class, new StringConverter());
- registry.put(Charset.class, new CharsetConverter());
- registry.put(File.class, new FileConverter());
- registry.put(URL.class, new UrlConverter());
- registry.put(URI.class, new UriConverter());
- registry.put(Class.class, new ClassConverter());
- registry.put(Pattern.class, new PatternConverter());
- registry.put(Provider.class, new SecurityProviderConverter());
- // Log4J
- registry.put(Level.class, new LevelConverter());
- registry.put(Filter.Result.class, new EnumConverter<Filter.Result>(Filter.Result.class));
- registry.put(Facility.class, new EnumConverter<Facility>(Facility.class));
- registry.put(Protocol.class, new EnumConverter<Protocol>(Protocol.class));
- registry.put(GelfLayout.CompressionType.class, new EnumConverter<GelfLayout.CompressionType>(
- GelfLayout.CompressionType.class));
- registry.put(HtmlLayout.FontSize.class, new EnumConverter<HtmlLayout.FontSize>(HtmlLayout.FontSize.class));
- registry.put(ConsoleAppender.Target.class, new EnumConverter<ConsoleAppender.Target>(
- ConsoleAppender.Target.class));
- }
-}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d33cda77/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/AbstractPluginVisitor.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/AbstractPluginVisitor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/AbstractPluginVisitor.java
index 2729fdc..22c62b3 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/AbstractPluginVisitor.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/AbstractPluginVisitor.java
@@ -22,7 +22,7 @@ import java.lang.reflect.Member;
import java.util.Map;
import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.config.plugins.util.TypeConverters;
+import org.apache.logging.log4j.core.config.plugins.convert.TypeConverters;
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
import org.apache.logging.log4j.core.util.Assert;
import org.apache.logging.log4j.status.StatusLogger;
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d33cda77/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConvertersTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConvertersTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConvertersTest.java
new file mode 100644
index 0000000..7c6dfb4
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConvertersTest.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.logging.log4j.core.config.plugins.convert;
+
+import java.io.File;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URI;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.security.Provider;
+import java.security.Security;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.layout.GelfLayout;
+import org.apache.logging.log4j.core.net.Facility;
+import org.apache.logging.log4j.core.util.Charsets;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests {@link TypeConverters}.
+ */
+@RunWith(Parameterized.class)
+public class TypeConvertersTest {
+
+ @SuppressWarnings("boxing")
+ @Parameterized.Parameters
+ public static Collection<Object[]> data() throws Exception {
+ final byte[] byteArray = {
+ (byte) 0xc7,
+ (byte) 0x73,
+ (byte) 0x21,
+ (byte) 0x8c,
+ (byte) 0x7e,
+ (byte) 0xc8,
+ (byte) 0xee,
+ (byte) 0x99 };
+ return Arrays.asList(
+ // Array format: value, expected, default, type
+ new Object[][]{
+ // boolean
+ { "true", true, null, Boolean.class },
+ { "false", false, null, Boolean.class },
+ { "True", true, null, Boolean.class },
+ { "TRUE", true, null, Boolean.class },
+ { "blah", false, null, Boolean.class }, // TODO: is this acceptable? it's how Boolean.parseBoolean works
+ { null, null, null, Boolean.class },
+ { null, true, "true", Boolean.class },
+ { "no", false, null, Boolean.class }, // TODO: see above
+ { "true", true, "false", boolean.class },
+ { "FALSE", false, "true", boolean.class },
+ { null, false, "false", boolean.class },
+ { "invalid", false, "false", boolean.class },
+ // byte
+ { "42", (byte)42, null, Byte.class },
+ { "53", (byte)53, null, Byte.class },
+ // char
+ { "A", 'A', null, char.class },
+ { "b", 'b', null, char.class },
+ { "b0", null, null, char.class },
+ // integer
+ { "42", 42, null, Integer.class },
+ { "53", 53, null, Integer.class },
+ { "-16", -16, null, Integer.class },
+ { "0", 0, null, Integer.class },
+ { "n", null, null, Integer.class },
+ { "n", 5, "5", Integer.class },
+ { "4.2", null, null, Integer.class },
+ { "4.2", 0, "0", Integer.class },
+ { null, null, null, Integer.class },
+ { "75", 75, "0", int.class },
+ { "-30", -30, "0", int.class },
+ { "0", 0, "10", int.class },
+ { null, 10, "10", int.class },
+ // longs
+ { "55", 55L, null, Long.class },
+ { "1234567890123456789", 1234567890123456789L, null, Long.class },
+ { "123123123L", null, null, Long.class },
+ { "123123123123", 123123123123L, null, Long.class },
+ { "-987654321", -987654321L, null, Long.class },
+ { "-45l", null, null, Long.class },
+ { "0", 0L, null, Long.class },
+ { "asdf", null, null, Long.class },
+ { "3.14", null, null, Long.class },
+ { "3.14", 0L, "0", Long.class },
+ { "*3", 1000L, "1000", Long.class },
+ { null, null, null, Long.class },
+ { "3000", 3000L, "0", long.class },
+ { "-543210", -543210L, "0", long.class },
+ { "22.7", -53L, "-53", long.class },
+ // short
+ { "42", (short)42, null, short.class },
+ { "53", (short)53, null, short.class },
+ { "-16", (short)-16, null, Short.class },
+ // Log4j
+ // levels
+ { "ERROR", Level.ERROR, null, Level.class },
+ { "WARN", Level.WARN, null, Level.class },
+ { "FOO", null, null, Level.class },
+ { "FOO", Level.DEBUG, "DEBUG", Level.class },
+ { "OFF", Level.OFF, null, Level.class },
+ { null, null, null, Level.class },
+ { null, Level.INFO, "INFO", Level.class },
+ // results
+ { "ACCEPT", Filter.Result.ACCEPT, null, Filter.Result.class },
+ { "NEUTRAL", Filter.Result.NEUTRAL, null, Filter.Result.class },
+ { "DENY", Filter.Result.DENY, null, Filter.Result.class },
+ { "NONE", null, null, Filter.Result.class },
+ { "NONE", Filter.Result.NEUTRAL, "NEUTRAL", Filter.Result.class },
+ { null, null, null, Filter.Result.class },
+ { null, Filter.Result.ACCEPT, "ACCEPT", Filter.Result.class },
+ // syslog facilities
+ { "KERN", Facility.KERN, "USER", Facility.class },
+ { "mail", Facility.MAIL, "KERN", Facility.class },
+ { "Cron", Facility.CRON, null, Facility.class },
+ { "not a real facility", Facility.AUTH, "auth", Facility.class },
+ { null, null, null, Facility.class },
+ // GELF compression types
+ { "GZIP", GelfLayout.CompressionType.GZIP, "GZIP", GelfLayout.CompressionType.class },
+ // arrays
+ { "123", "123".toCharArray(), null, char[].class },
+ { "123", "123".getBytes(Charset.defaultCharset()), null, byte[].class },
+ { "0xC773218C7EC8EE99", byteArray, null, byte[].class },
+ { "0xc773218c7ec8ee99", byteArray, null, byte[].class },
+ { "Base64:cGxlYXN1cmUu", "pleasure.".getBytes("US-ASCII"), null, byte[].class },
+ // JRE
+ // JRE Charset
+ { "UTF-8", Charsets.UTF_8, null, Charset.class },
+ { "ASCII", Charset.forName("ASCII"), "UTF-8", Charset.class },
+ { "Not a real charset", Charsets.UTF_8, "UTF-8", Charset.class },
+ { null, Charsets.UTF_8, "UTF-8", Charset.class },
+ { null, null, null, Charset.class },
+ // JRE File
+ { "c:/temp", new File("c:/temp"), null, File.class },
+ // JRE Class
+ { TypeConvertersTest.class.getName(), TypeConvertersTest.class, null, Class.class },
+ { "\n", null, null, Class.class },
+ // JRE URL
+ { "http://locahost", new URL("http://locahost"), null, URL.class },
+ { "\n", null, null, URL.class },
+ // JRE URI
+ { "http://locahost", new URI("http://locahost"), null, URI.class },
+ { "\n", null, null, URI.class },
+ // JRE BigInteger
+ { "9223372036854775817000", new BigInteger("9223372036854775817000"), null, BigInteger.class },
+ { "\n", null, null, BigInteger.class },
+ // JRE BigInteger
+ { "9223372036854775817000.99999", new BigDecimal("9223372036854775817000.99999"), null, BigDecimal.class },
+ { "\n", null, null, BigDecimal.class },
+ // JRE Security Provider
+ { Security.getProviders()[0].getName(), Security.getProviders()[0], null, Provider.class },
+ { "\n", null, null, Provider.class },
+ }
+ );
+ }
+
+ private final String value;
+ private final Object expected;
+ private final String defaultValue;
+ private final Class<?> clazz;
+
+ public TypeConvertersTest(final String value, final Object expected, final String defaultValue, final Class<?> clazz) {
+ this.value = value;
+ this.expected = expected;
+ this.defaultValue = defaultValue;
+ this.clazz = clazz;
+ }
+
+ @Test
+ public void testConvert() throws Exception {
+ final Object actual = TypeConverters.convert(value, clazz, defaultValue);
+ final String assertionMessage = "\nGiven: " + value + "\nDefault: " + defaultValue;
+ if (expected != null && expected instanceof char[]) {
+ assertArrayEquals(assertionMessage, (char[]) expected, (char[]) actual);
+ } else if (expected != null && expected instanceof byte[]) {
+ assertArrayEquals(assertionMessage, (byte[]) expected, (byte[]) actual);
+ } else {
+ assertEquals(assertionMessage, expected, actual);
+ }}
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d33cda77/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/util/TypeConvertersTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/util/TypeConvertersTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/util/TypeConvertersTest.java
deleted file mode 100644
index 061817b..0000000
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/util/TypeConvertersTest.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.logging.log4j.core.config.plugins.util;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.net.URI;
-import java.net.URL;
-import java.nio.charset.Charset;
-import java.security.Provider;
-import java.security.Security;
-import java.util.Arrays;
-import java.util.Collection;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.core.Filter;
-import org.apache.logging.log4j.core.layout.GelfLayout;
-import org.apache.logging.log4j.core.net.Facility;
-import org.apache.logging.log4j.core.util.Charsets;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-/**
- * Tests {@link TypeConverters}.
- */
-@RunWith(Parameterized.class)
-public class TypeConvertersTest {
-
- @SuppressWarnings("boxing")
- @Parameterized.Parameters
- public static Collection<Object[]> data() throws Exception {
- final byte[] byteArray = {
- (byte) 0xc7,
- (byte) 0x73,
- (byte) 0x21,
- (byte) 0x8c,
- (byte) 0x7e,
- (byte) 0xc8,
- (byte) 0xee,
- (byte) 0x99 };
- return Arrays.asList(
- // Array format: value, expected, default, type
- new Object[][]{
- // boolean
- { "true", true, null, Boolean.class },
- { "false", false, null, Boolean.class },
- { "True", true, null, Boolean.class },
- { "TRUE", true, null, Boolean.class },
- { "blah", false, null, Boolean.class }, // TODO: is this acceptable? it's how Boolean.parseBoolean works
- { null, null, null, Boolean.class },
- { null, true, "true", Boolean.class },
- { "no", false, null, Boolean.class }, // TODO: see above
- { "true", true, "false", boolean.class },
- { "FALSE", false, "true", boolean.class },
- { null, false, "false", boolean.class },
- { "invalid", false, "false", boolean.class },
- // byte
- { "42", (byte)42, null, Byte.class },
- { "53", (byte)53, null, Byte.class },
- // char
- { "A", 'A', null, char.class },
- { "b", 'b', null, char.class },
- { "b0", null, null, char.class },
- // integer
- { "42", 42, null, Integer.class },
- { "53", 53, null, Integer.class },
- { "-16", -16, null, Integer.class },
- { "0", 0, null, Integer.class },
- { "n", null, null, Integer.class },
- { "n", 5, "5", Integer.class },
- { "4.2", null, null, Integer.class },
- { "4.2", 0, "0", Integer.class },
- { null, null, null, Integer.class },
- { "75", 75, "0", int.class },
- { "-30", -30, "0", int.class },
- { "0", 0, "10", int.class },
- { null, 10, "10", int.class },
- // longs
- { "55", 55L, null, Long.class },
- { "1234567890123456789", 1234567890123456789L, null, Long.class },
- { "123123123L", null, null, Long.class },
- { "123123123123", 123123123123L, null, Long.class },
- { "-987654321", -987654321L, null, Long.class },
- { "-45l", null, null, Long.class },
- { "0", 0L, null, Long.class },
- { "asdf", null, null, Long.class },
- { "3.14", null, null, Long.class },
- { "3.14", 0L, "0", Long.class },
- { "*3", 1000L, "1000", Long.class },
- { null, null, null, Long.class },
- { "3000", 3000L, "0", long.class },
- { "-543210", -543210L, "0", long.class },
- { "22.7", -53L, "-53", long.class },
- // short
- { "42", (short)42, null, short.class },
- { "53", (short)53, null, short.class },
- { "-16", (short)-16, null, Short.class },
- // Log4j
- // levels
- { "ERROR", Level.ERROR, null, Level.class },
- { "WARN", Level.WARN, null, Level.class },
- { "FOO", null, null, Level.class },
- { "FOO", Level.DEBUG, "DEBUG", Level.class },
- { "OFF", Level.OFF, null, Level.class },
- { null, null, null, Level.class },
- { null, Level.INFO, "INFO", Level.class },
- // results
- { "ACCEPT", Filter.Result.ACCEPT, null, Filter.Result.class },
- { "NEUTRAL", Filter.Result.NEUTRAL, null, Filter.Result.class },
- { "DENY", Filter.Result.DENY, null, Filter.Result.class },
- { "NONE", null, null, Filter.Result.class },
- { "NONE", Filter.Result.NEUTRAL, "NEUTRAL", Filter.Result.class },
- { null, null, null, Filter.Result.class },
- { null, Filter.Result.ACCEPT, "ACCEPT", Filter.Result.class },
- // syslog facilities
- { "KERN", Facility.KERN, "USER", Facility.class },
- { "mail", Facility.MAIL, "KERN", Facility.class },
- { "Cron", Facility.CRON, null, Facility.class },
- { "not a real facility", Facility.AUTH, "auth", Facility.class },
- { null, null, null, Facility.class },
- // GELF compression types
- { "GZIP", GelfLayout.CompressionType.GZIP, "GZIP", GelfLayout.CompressionType.class },
- // arrays
- { "123", "123".toCharArray(), null, char[].class },
- { "123", "123".getBytes(Charset.defaultCharset()), null, byte[].class },
- { "0xC773218C7EC8EE99", byteArray, null, byte[].class },
- { "0xc773218c7ec8ee99", byteArray, null, byte[].class },
- { "Base64:cGxlYXN1cmUu", "pleasure.".getBytes("US-ASCII"), null, byte[].class },
- // JRE
- // JRE Charset
- { "UTF-8", Charsets.UTF_8, null, Charset.class },
- { "ASCII", Charset.forName("ASCII"), "UTF-8", Charset.class },
- { "Not a real charset", Charsets.UTF_8, "UTF-8", Charset.class },
- { null, Charsets.UTF_8, "UTF-8", Charset.class },
- { null, null, null, Charset.class },
- // JRE File
- { "c:/temp", new File("c:/temp"), null, File.class },
- // JRE Class
- { TypeConvertersTest.class.getName(), TypeConvertersTest.class, null, Class.class },
- { "\n", null, null, Class.class },
- // JRE URL
- { "http://locahost", new URL("http://locahost"), null, URL.class },
- { "\n", null, null, URL.class },
- // JRE URI
- { "http://locahost", new URI("http://locahost"), null, URI.class },
- { "\n", null, null, URI.class },
- // JRE BigInteger
- { "9223372036854775817000", new BigInteger("9223372036854775817000"), null, BigInteger.class },
- { "\n", null, null, BigInteger.class },
- // JRE BigInteger
- { "9223372036854775817000.99999", new BigDecimal("9223372036854775817000.99999"), null, BigDecimal.class },
- { "\n", null, null, BigDecimal.class },
- // JRE Security Provider
- { Security.getProviders()[0].getName(), Security.getProviders()[0], null, Provider.class },
- { "\n", null, null, Provider.class },
- }
- );
- }
-
- private final String value;
- private final Object expected;
- private final String defaultValue;
- private final Class<?> clazz;
-
- public TypeConvertersTest(final String value, final Object expected, final String defaultValue, final Class<?> clazz) {
- this.value = value;
- this.expected = expected;
- this.defaultValue = defaultValue;
- this.clazz = clazz;
- }
-
- @Test
- public void testConvert() throws Exception {
- final Object actual = TypeConverters.convert(value, clazz, defaultValue);
- final String assertionMessage = "\nGiven: " + value + "\nDefault: " + defaultValue;
- if (expected != null && expected instanceof char[]) {
- assertArrayEquals(assertionMessage, (char[]) expected, (char[]) actual);
- } else if (expected != null && expected instanceof byte[]) {
- assertArrayEquals(assertionMessage, (byte[]) expected, (byte[]) actual);
- } else {
- assertEquals(assertionMessage, expected, actual);
- }}
-}