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