View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
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   * Utility class which can convert string into objects.
26   * 
27   * @author Ceki Gülcü
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       * Convert <code>val</code> a String parameter to an object of a given type.
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      // returned value may be null and in most cases it is null.
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 }