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   * @author Ceki Gülcü
27   *
28   */
29  public class StringToObjectConverter {
30  
31      private static final Class<?>[] STING_CLASS_PARAMETER = new Class[] { String.class };
32  
33      static public boolean canBeBuiltFromSimpleString(Class<?> parameterClass) {
34          Package p = parameterClass.getPackage();
35          if (parameterClass.isPrimitive()) {
36              return true;
37          } else if (p != null && "java.lang".equals(p.getName())) {
38              return true;
39          } else if (followsTheValueOfConvention(parameterClass)) {
40              return true;
41          } else if (parameterClass.isEnum()) {
42              return true;
43          } else if (isOfTypeCharset(parameterClass)) {
44              return true;
45          }
46          return false;
47      }
48  
49      /**
50       * Convert <code>val</code> a String parameter to an object of a given type.
51       */
52      @SuppressWarnings("unchecked")
53      public static Object convertArg(ContextAware ca, String val, Class<?> type) {
54          if (val == null) {
55              return null;
56          }
57          String v = val.trim();
58          if (String.class.isAssignableFrom(type)) {
59              return v;
60          } else if (Integer.TYPE.isAssignableFrom(type)) {
61              return Integer.valueOf(v);
62          } else if (Long.TYPE.isAssignableFrom(type)) {
63              return Long.valueOf(v);
64          } else if (Float.TYPE.isAssignableFrom(type)) {
65              return Float.valueOf(v);
66          } else if (Double.TYPE.isAssignableFrom(type)) {
67              return Double.valueOf(v);
68          } else if (Boolean.TYPE.isAssignableFrom(type)) {
69              if ("true".equalsIgnoreCase(v)) {
70                  return Boolean.TRUE;
71              } else if ("false".equalsIgnoreCase(v)) {
72                  return Boolean.FALSE;
73              }
74          } else if (type.isEnum()) {
75              return convertToEnum(ca, v, (Class<? extends Enum<?>>) type);
76          } else if (StringToObjectConverter.followsTheValueOfConvention(type)) {
77              return convertByValueOfMethod(ca, type, v);
78          } else if (isOfTypeCharset(type)) {
79              return convertToCharset(ca, val);
80          }
81  
82          return null;
83      }
84  
85      static private boolean isOfTypeCharset(Class<?> type) {
86          return Charset.class.isAssignableFrom(type);
87      }
88  
89      static private Charset convertToCharset(ContextAware ca, String val) {
90          try {
91              return Charset.forName(val);
92          } catch (UnsupportedCharsetException e) {
93              ca.addError("Failed to get charset [" + val + "]", e);
94              return null;
95          }
96      }
97  
98      // returned value may be null and in most cases it is null.
99      public static Method getValueOfMethod(Class<?> type) {
100         try {
101             return type.getMethod(CoreConstants.VALUE_OF, STING_CLASS_PARAMETER);
102         } catch (NoSuchMethodException e) {
103             return null;
104         } catch (SecurityException e) {
105             return null;
106         }
107     }
108 
109     static private boolean followsTheValueOfConvention(Class<?> parameterClass) {
110         Method valueOfMethod = getValueOfMethod(parameterClass);
111         if (valueOfMethod == null)
112             return false;
113 
114         int mod = valueOfMethod.getModifiers();
115         return Modifier.isStatic(mod);
116     }
117 
118     private static Object convertByValueOfMethod(ContextAware ca, Class<?> type, String val) {
119         try {
120             Method valueOfMethod = type.getMethod(CoreConstants.VALUE_OF, STING_CLASS_PARAMETER);
121             return valueOfMethod.invoke(null, val);
122         } catch (Exception e) {
123             ca.addError("Failed to invoke " + CoreConstants.VALUE_OF + "{} method in class [" + type.getName() + "] with value [" + val + "]");
124             return null;
125         }
126     }
127 
128     @SuppressWarnings({ "unchecked", "rawtypes" })
129     private static Object convertToEnum(ContextAware ca, String val, Class<? extends Enum> enumType) {
130         return Enum.valueOf(enumType, val);
131     }
132 
133     boolean isBuildableFromSimpleString() {
134         return false;
135     }
136 }