001: /*
002: * This file is part of JGAP.
003: *
004: * JGAP offers a dual license model containing the LGPL as well as the MPL.
005: *
006: * For licencing information please see the file license.txt included with JGAP
007: * or have a look at the top of class org.jgap.Chromosome which representatively
008: * includes the JGAP license policy applicable for any file delivered with JGAP.
009: */
010: package org.jgap.data.config;
011:
012: import java.util.*;
013: import org.jgap.*;
014: import java.lang.reflect.*;
015:
016: /**
017: * The ConfigurationHandler for the Configuration class itself. This is the
018: * entry point for a Configuration.
019: * In other words this is for dynamically building up a Configuration.
020: *
021: * @author Siddhartha Azad
022: * @author Klaus Meffert
023: * @since 2.3
024: * */
025: public class RootConfigurationHandler implements ConfigurationHandler {
026: /** String containing the CVS revision. Read out via reflection!*/
027: private final static String CVS_REVISION = "$Revision: 1.11 $";
028:
029: // Namespace
030: private final static String CONFIG_NAMESPACE = "org.jgap.Configuration";
031:
032: // constants to indicate various properties
033: // ----------------------------------------
034: private final static String GENETIC_OPS = "GeneticOperators";
035:
036: private final static String NATURAL_SELS = "NaturalSelectors";
037:
038: private Configurable m_configurable;
039:
040: /**
041: * @return Name of this Configuration Object (name of what you are
042: * configuring) to be used in the properties file.
043: *
044: * @since 2.3
045: * */
046: public String getName() {
047: return "Configuration";
048: }
049:
050: /**
051: * Return the information to generate the GUI for configuring this class.
052: * @return a list of ConfigProperty objects
053: * @since 2.3
054: * */
055: public List getConfigProperties() {
056: return null;
057: }
058:
059: /**
060: * Get the namespace to be used in the config file for the Configurable
061: * this ConfigurationHandler belongs to.
062: * @return the namespace of the Configurable
063: *
064: * @author Siddhartha Azad
065: * @since 2.3
066: * */
067: public String getNS() {
068: return CONFIG_NAMESPACE;
069: }
070:
071: /**
072: * Method that will populate an Configurable with the properties in the
073: * config file.
074: *
075: * @throws ConfigException
076: * @throws InvalidConfigurationException
077: *
078: * @author Siddhartha Azad
079: * @since 2.3
080: * */
081: public void readConfig() throws ConfigException,
082: InvalidConfigurationException {
083: // TODO adapt to new concept of configuration via reflection and marker
084: // interface
085: // set the namespace to get the properties from
086: ConfigFileReader.instance().setNS(CONFIG_NAMESPACE);
087: String value = ConfigFileReader.instance().getValue(
088: "m_populationSize");
089: try {
090: if (value != null) {
091: setConfigProperty(m_configurable, "m_populationSize",
092: value);
093: }
094: } catch (IllegalAccessException ex) {
095: ex.printStackTrace();
096: throw new InvalidConfigurationException(ex.getMessage());
097: }
098: // go through all genetic operators and configure them
099: configureClass(GENETIC_OPS);
100: // go through all natural selectors and configure them
101: configureClass(NATURAL_SELS);
102: }
103:
104: /**
105: * Set the Configurable to which this ConfigurationHandler belongs.
106: * @param a_configurable the Configurable to which this ConfigurationHandler
107: * belongs
108: *
109: * @author Siddhartha Azad
110: * @since 2.3
111: * */
112: public void setConfigurable(Configurable a_configurable) {
113: m_configurable = a_configurable;
114: }
115:
116: /**
117: * Sets the property of a configurable to a given value. Uses reflection to
118: * do so. Queries the method getConfigVarName for the name of the field
119: * hosting the configurable properties.
120: *
121: * @param a_configurable the configurable to use
122: * @param a_propertyName the property to set
123: * @param a_value the value to assign to the property
124: * @throws IllegalAccessException
125: *
126: * @author Klaus Meffert
127: * @since 2.6
128: */
129: public void setConfigProperty(Object a_configurable,
130: String a_propertyName, String a_value)
131: throws IllegalAccessException {
132: // Use following in case variable name "m_config" should be determined
133: // dynamically.
134: // Method m = null;
135: // try {
136: // m = a_configurable.getClass().getDeclaredMethod("getConfigVarName",
137: // new Class[0]);
138: // } catch (NoSuchMethodException nex) {
139: // // nothing to set here
140: // return;
141: // }
142: String configVarName = "m_config"; //(String)m.invoke(a_configurable, new Object[0]);
143: Field configVar = getPrivateField(a_configurable, configVarName);
144: configVar.setAccessible(true);
145: Object configObj = configVar.get(a_configurable);
146: Field propertyVar = getPrivateField(configObj, a_propertyName);
147: propertyVar.setAccessible(true);
148: Class type = propertyVar.getType();
149: if (type.equals(boolean.class)) {
150: propertyVar.setBoolean(configObj, Boolean.valueOf(a_value)
151: .booleanValue());
152: } else if (type.equals(byte.class)) {
153: propertyVar.setByte(configObj, Byte.valueOf(a_value)
154: .byteValue());
155: } else if (type.equals(char.class)) {
156: propertyVar.setChar(configObj, a_value.charAt(0));
157: } else if (type.equals(double.class)) {
158: propertyVar.setDouble(configObj, Double.valueOf(a_value)
159: .doubleValue());
160: } else if (type.equals(float.class)) {
161: propertyVar.setFloat(configObj, Float.valueOf(a_value)
162: .floatValue());
163: } else if (type.equals(int.class)) {
164: propertyVar.setInt(configObj, Integer.valueOf(a_value)
165: .intValue());
166: } else if (type.equals(long.class)) {
167: propertyVar.setLong(configObj, Long.valueOf(a_value)
168: .longValue());
169: } else if (type.equals(short.class)) {
170: propertyVar.setShort(configObj, Short.valueOf(a_value)
171: .shortValue());
172: } else if (type.equals(String.class)) {
173: propertyVar.set(configObj, a_value);
174: } else {
175: throw new RuntimeException("Unknown field type: "
176: + type.getName());
177: }
178: }
179:
180: /**
181: * Helper method: Read a private field.
182: * @param a_instance the instance the field is contained with
183: * @param a_fieldName the name of the field to read
184: * @return the Field object or null, if none found
185: *
186: * @author Klaus Meffert
187: * @since 2.6
188: */
189: public static Field getPrivateField(Object a_instance,
190: String a_fieldName) {
191: final Field fields[] = a_instance.getClass()
192: .getDeclaredFields();
193: for (int i = 0; i < fields.length; ++i) {
194: if (a_fieldName.equals(fields[i].getName())) {
195: fields[i].setAccessible(true);
196: return fields[i];
197: }
198: }
199: return null;
200: }
201:
202: /**
203: * Retrieve all instances of a certain property from the config file reader
204: * and configure each of these.
205: * @param className the name of the property to configure
206: * @throws ConfigException
207: *
208: * @author Siddhartha Azad
209: * @since 2.4
210: * */
211: public static void configureClass(String className)
212: throws ConfigException {
213: List values = ConfigFileReader.instance().getValues(className);
214: if (values != null && values.size() > 0) {
215: String cName = "";
216: // iterate through all instances of this property and create Configurables
217: // for them, then configure these
218: for (Iterator iter = values.iterator(); iter.hasNext();) {
219: try {
220: cName = (String) iter.next();
221: Class genClass = Class.forName(cName);
222: Configurable conObj = (Configurable) genClass
223: .newInstance();
224: //TODO ConfigurationHandler cHandler = conObj.getConfigurationHandler();
225: //TODO cHandler.readConfig();
226: } catch (Exception ex) {
227: throw new ConfigException(
228: "Error while configuring " + className
229: + "." + cName);
230: }
231: }
232: }
233: }
234: }
|