00001 00005 package edu.mit.csail.sdg.squander.options; 00006 00007 import java.lang.reflect.Field; 00008 import java.util.HashMap; 00009 import java.util.LinkedList; 00010 import java.util.List; 00011 import java.util.Map; 00012 00013 import edu.mit.csail.sdg.squander.utils.ReflectionUtils; 00014 00015 00016 public class ConfigLoader { 00017 00018 public static String[] loadOptions(Object confObj, String[] args) { 00019 Class<?> cls = confObj.getClass(); 00020 List<String> free = new LinkedList<String>(); 00021 for (String arg : args) { 00022 if (!arg.startsWith("--")) { 00023 free.add(arg); 00024 continue; 00025 } 00026 String[] pair = arg.substring(2).split("="); 00027 String optionName = pair[0]; 00028 String optionValue = null; 00029 if (pair.length == 2) 00030 optionValue = pair[1]; 00031 String optName = optionName.replaceAll("-", "_"); 00032 Field f = getField(cls, optName); 00033 if (f == null) 00034 f = getField(cls, optName.toUpperCase()); 00035 if (f == null) { 00036 error("Unknonwn option: " + arg); 00037 continue; 00038 } 00039 00040 Class<?> fieldType = f.getType(); 00041 if (fieldType == boolean.class) { 00042 setBoolean(confObj, optionName, optionValue, f); 00043 } else if (fieldType == int.class) { 00044 setInt(confObj, optionName, optionValue, f); 00045 } else if (fieldType == Class.class) { 00046 setClass(confObj, optionName, optionValue, f); 00047 } else if (fieldType.isEnum()) { 00048 setEnum(confObj, optionName, optionValue, f, fieldType); 00049 } else if (fieldType == String.class) { 00050 setString(confObj, optionName, optionValue, f); 00051 } else { 00052 error(String.format("Cannot set value for a field of type %s", fieldType.getName())); 00053 } 00054 } 00055 return free.toArray(new String[0]); 00056 } 00057 00058 private static Field getField(Class<?> cls, String name) { 00059 try { 00060 return ReflectionUtils.getField(cls, name); 00061 } catch (Exception e) { 00062 return null; 00063 } 00064 } 00065 00066 private static void setString(Object confObj, String optionName, String optionValue, Field f) { 00067 ReflectionUtils.setFieldValue(confObj, f, optionValue); 00068 } 00069 00070 private static void setEnum(Object confObj, String optionName, String optionValue, Field f, 00071 Class<?> fieldType) { 00072 Map<String, Object> enums = new HashMap<String, Object>(); 00073 for (Object enumConst : fieldType.getEnumConstants()) { 00074 enums.put(enumConst.toString(), enumConst); 00075 } 00076 if (optionValue == null) 00077 error(String.format("Must provide a value for enum option %s. Legal values: %s", 00078 optionName, enums.keySet())); 00079 String val = optionValue.replaceAll("-", "_"); 00080 Object obj = enums.get(val); 00081 if (obj == null) { 00082 error(String.format("Invalid value for option %s: %s. Legal values: %s", 00083 optionName, optionValue, enums.keySet())); 00084 } else { 00085 ReflectionUtils.setFieldValue(confObj, f, obj); 00086 } 00087 } 00088 00089 private static void setClass(Object confObj, String optionName, String optionValue, Field f) { 00090 try { 00091 ReflectionUtils.setFieldValue(confObj, f, Class.forName(optionValue)); 00092 } catch (ClassNotFoundException e) { 00093 error("Could not find a class with name: " + optionValue); 00094 } 00095 } 00096 00097 private static void setInt(Object confObj, String optionName, String optionValue, Field f) { 00098 if (optionValue == null) 00099 error(String.format("Must provide a value for integer option %s", optionName)); 00100 try { 00101 ReflectionUtils.setFieldValue(confObj, f, Integer.parseInt(optionValue)); 00102 } catch (NumberFormatException e) { 00103 error(String.format("Invalid value for integer option %s: %s", optionName, optionValue)); 00104 } 00105 } 00106 00107 private static void setBoolean(Object confObj, String optionName, String optionValue, Field f) { 00108 if (optionValue != null) { 00109 if (optionValue.toLowerCase().equals("true")) 00110 ReflectionUtils.setFieldValue(confObj, f, true); 00111 else if (optionValue.toLowerCase().equals("false")) 00112 ReflectionUtils.setFieldValue(confObj, f, false); 00113 else 00114 error(String.format("Invalid value for boolean option %s: %s", optionName, optionValue)); 00115 } else { 00116 ReflectionUtils.setFieldValue(confObj, f, true); 00117 } 00118 } 00119 00120 private static void error(String msg) { 00121 System.err.println(msg); 00122 } 00123 00124 }