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 }