1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.joran.util;
15
16 import ch.qos.logback.core.CoreConstants;
17 import ch.qos.logback.core.spi.ContextAware;
18
19 import java.lang.reflect.Method;
20 import java.lang.reflect.Modifier;
21 import java.nio.charset.Charset;
22 import java.nio.charset.UnsupportedCharsetException;
23
24 import static ch.qos.logback.core.CoreConstants.NULL_STR;
25
26
27
28
29
30
31
32 public class StringToObjectConverter {
33
34 private static final Class<?>[] STRING_CLASS_PARAMETER = new Class[] { String.class };
35
36 static public boolean canBeBuiltFromSimpleString(Class<?> parameterClass) {
37 Package p = parameterClass.getPackage();
38 if (parameterClass.isPrimitive()) {
39 return true;
40 } else if (p != null && "java.lang".equals(p.getName())) {
41 return true;
42 } else if (followsTheValueOfConvention(parameterClass)) {
43 return true;
44 } else if (parameterClass.isEnum()) {
45 return true;
46 } else if (isOfTypeCharset(parameterClass)) {
47 return true;
48 }
49 return false;
50 }
51
52
53
54
55 @SuppressWarnings("unchecked")
56 static public Object convertArg(ContextAware ca, String val, Class<?> type) {
57 if (val == null) {
58 return null;
59 }
60 String v = val.trim();
61 if (String.class.isAssignableFrom(type)) {
62 return v;
63 } else if (Integer.TYPE.isAssignableFrom(type)) {
64 return Integer.valueOf(v);
65 } else if (Long.TYPE.isAssignableFrom(type)) {
66 return Long.valueOf(v);
67 } else if (Float.TYPE.isAssignableFrom(type)) {
68 return Float.valueOf(v);
69 } else if (Double.TYPE.isAssignableFrom(type)) {
70 return Double.valueOf(v);
71 } else if (Boolean.TYPE.isAssignableFrom(type)) {
72 if ("true".equalsIgnoreCase(v)) {
73 return Boolean.TRUE;
74 } else if ("false".equalsIgnoreCase(v)) {
75 return Boolean.FALSE;
76 }
77 } else if (type.isEnum()) {
78 return convertToEnum(ca, v, (Class<? extends Enum<?>>) type);
79 } else if (StringToObjectConverter.followsTheValueOfConvention(type)) {
80 return convertByValueOfMethod(ca, type, v);
81 } else if (isOfTypeCharset(type)) {
82 return convertToCharset(ca, val);
83 }
84
85 return null;
86 }
87
88 static private boolean isOfTypeCharset(Class<?> type) {
89 return Charset.class.isAssignableFrom(type);
90 }
91
92 static private Charset convertToCharset(ContextAware ca, String val) {
93
94 if (NULL_STR.equalsIgnoreCase(val)) {
95 ca.addInfo("Converting the string \"null\" as Charset.defaultCharset()");
96 return Charset.defaultCharset();
97 }
98
99 try {
100 return Charset.forName(val);
101 } catch (UnsupportedCharsetException e) {
102 ca.addError("Failed to get charset [" + val + "]", e);
103 return null;
104 }
105 }
106
107
108 static public Method getValueOfMethod(Class<?> type) {
109 try {
110 return type.getMethod(CoreConstants.VALUE_OF, STRING_CLASS_PARAMETER);
111 } catch (NoSuchMethodException e) {
112 return null;
113 } catch (SecurityException e) {
114 return null;
115 }
116 }
117
118 static public boolean followsTheValueOfConvention(Class<?> parameterClass) {
119 Method valueOfMethod = getValueOfMethod(parameterClass);
120 if (valueOfMethod == null)
121 return false;
122
123 int mod = valueOfMethod.getModifiers();
124 return Modifier.isStatic(mod);
125 }
126
127 private static Object convertByValueOfMethod(ContextAware ca, Class<?> type, String val) {
128 try {
129 Method valueOfMethod = type.getMethod(CoreConstants.VALUE_OF, STRING_CLASS_PARAMETER);
130 return valueOfMethod.invoke(null, val);
131 } catch (Exception e) {
132 ca.addError("Failed to invoke " + CoreConstants.VALUE_OF + "{} method in class [" + type.getName()
133 + "] with value [" + val + "]");
134 return null;
135 }
136 }
137
138 @SuppressWarnings({ "unchecked", "rawtypes" })
139 private static Object convertToEnum(ContextAware ca, String val, Class<? extends Enum> enumType) {
140 return Enum.valueOf(enumType, val);
141 }
142
143 boolean isBuildableFromSimpleString() {
144 return false;
145 }
146 }