Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: feynman/framework/simulation/Marshaller.java


1   /*
2    * $Header: /cvsroot/feynman/src/feynman/framework/simulation/Marshaller.java,v 1.1.1.1 2002/11/12 02:25:41 wesley_bailey Exp $
3    * $Revision: 1.1.1.1 $
4    * $Date: 2002/11/12 02:25:41 $
5    * $Copyright: Copyright (C) 2002 Path Integral Software $
6    */
7   package feynman.framework.simulation;
8   
9   import org.apache.regexp.RE;
10  import org.apache.regexp.RESyntaxException;
11  import java.io.*;
12  import java.util.*;
13  import java.lang.reflect.*;
14  
15  /**
16   * Utility class to load the properties file that the user has defined.  If
17   * there is a switch to an XML format and using a real Marshalling/Unmarshalling
18   * tool like Castor, then this class can easily be refactored to an adaptor class.
19   * <p>
20   * The constructor is private since this is a utility class so there is no instance
21   * of this class to create or get.  To use this class treat it just like the Math
22   * utility class in the following manner:
23   * <p>
24   * <pre>
25   * Simulation simulation = Marshaller.unmarshall("Simulation.properties");
26   * </pre>
27   * </p>
28   *
29   * @author Wes Bailey
30   * @version $Revision: 1.1.1.1 $ $Date: 2002/11/12 02:25:41 $
31   */
32  public class Marshaller {
33    
34    // Define instance variables.
35    private static File file;
36    private static FileWriter fw;
37    private static FileInputStream fin;
38    private static PrintWriter pw;
39    private static Properties props;
40    
41    /**
42     * This is a utility class so there is no instance of the class to be created or
43     * retrieved.
44     */
45    private Marshaller() {
46      // utility class
47    }
48    
49    /**
50     * Method to save a serialized version of the simulation object.
51     *
52     * @param sim The simulation bean to serialize.
53     * @param outfile The file to save the contents of the bean to.
54     */
55    public static void marshall(Simulation sim, String outfile) throws MarshallingException {
56      
57      try {
58        file = new File(outfile);
59        fw = new FileWriter(file);
60        pw = new PrintWriter(fw);
61      
62        pw.println(sim.toString());
63      
64        pw.close();
65        fw.close();
66      }
67      catch (IOException e) {
68        throw new MarshallingException(e.toString());
69      }
70      
71    }
72    
73    /**
74     * Method to create a simulation object with attribute values specified by the
75     * properties file descriptoin of the object.
76     *
77     * @param infile The name of the properties file to parse and create the bean from.
78     */
79    public static Simulation unmarshall(String infile) throws MarshallingException {
80      
81      // The simulation is a singleton class.
82      Simulation sim = Simulation.getInstance();
83      
84      // Prepare for reflection operations to invoke the correct methods from the
85      // properties file.
86      Method [] methods = sim.getClass().getMethods();
87      
88      try {
89        
90        // Define the properties file used to define the simulation bean
91        file = new File(infile);
92        fin = new FileInputStream(file);
93        
94        // Create the properties based on the file
95        props = new Properties();
96        props.load(fin);
97        
98        /*
99         * For debugging...
100       for (Enumeration e = props.propertyNames(); e.hasMoreElements(); ) {
101         String name = (String) e.nextElement();
102         System.out.println("name: " + name + "\t value: " + props.getProperty(name));
103       }
104       */
105       
106       // Setup validation regular expressions.
107       RE stringRegexp;
108       RE intRegexp;
109       RE decimalRegexp;
110       RE booleanRegexp;
111       try {
112         stringRegexp = new RE("^[a-zA-Z\\.]*$");
113         intRegexp = new RE("^[0-9]*$");
114         decimalRegexp = new RE("^[0-9]*\\.[0-9]*$");
115         booleanRegexp = new RE("^(true|false)$");
116       }
117       catch (RESyntaxException e) {
118         throw new MarshallingException("Please report the following error as a bug report: " + e.toString());
119       }
120       
121       // Create the array to be used in the method.invoke(Object obj, Object [] objs)
122       Object [] invokeParam = new Object[1]; 
123       
124       // For each method in the array, examine and determine if we have a setter
125       // method.  If we do then load the appropriate value from the properties file.
126       for (int i=0; i<methods.length; i++) {
127         
128         // Work with the method object as the loop, and not the properties.  Make it
129         // easier later when we want to invoke the actual method.
130         Method method = methods[i];
131         
132         // Catch on the setter methods.  They start with the string set and
133         // have only one parameter.
134         if (method.getName().startsWith("set")) {
135           
136           // Check the documentation for the Class object if this doesn't make
137           // sense to you.
138           Class [] params = method.getParameterTypes();
139           
140           if (params.length == 1) {
141             
142             // Should be obvious what we are capturing here.
143             Class param = params[0];
144             String paramType = param.getName();
145             String propName = method.getName().substring(3);
146             String propValue = props.getProperty(propName);
147             
148             /*
149              * Test each based on the parameter type.  If there is a property 
150              * that is assigned, then test if the value is in the correct format
151              * using the regular expressions to test validity.  If they are valid,
152              * then invoke the setter method for the property on the Simulation sim
153              * object with the appropriate parameter array.  Throw a marshalling
154              * exception with more information to the user on the invalid property
155              * otherwise.
156              */
157             if (!(propValue == null)) {
158               if (paramType.equals("int")) {
159                 if(intRegexp.match(propValue)) {
160                   invokeParam[0] = new Integer(propValue);
161                   method.invoke(sim, invokeParam);
162                 } else {
163                   throw new MarshallingException("Invalid " + propName + " value: " + propValue);
164                 }
165               } else if (paramType.equals("double")) {
166                 if (decimalRegexp.match(propValue)) {
167                   invokeParam[0] = new Double(propValue);
168                   method.invoke(sim, invokeParam);
169                 } else {
170                   throw new MarshallingException("Invalid " + propName + " value: " + propValue);
171                 }
172               } else if (paramType.equals("java.lang.String")) {
173                 if (stringRegexp.match(propValue)) {
174                   invokeParam[0] = propValue;
175                   method.invoke(sim, invokeParam);
176                 } else {
177                   throw new MarshallingException("Invalid " + propName + " value: " + propValue);
178                 }
179               } else if (paramType.equals("boolean")) {
180                 if (booleanRegexp.match(propValue)) {
181                   invokeParam[0] = new Boolean(propValue);
182                   method.invoke(sim, invokeParam);
183                 } else {
184                   throw new MarshallingException("Invalid " + propName + " value: " + propValue);
185                 }
186               }
187             }
188           }
189         }
190       }
191       
192       // Close up the properties file input stream
193       fin.close();
194       
195       // Return the constructed bean.
196       return sim;
197     
198     }
199     catch (IllegalAccessException e) {
200       throw new MarshallingException("Can't access property: " + e.toString());
201     }
202     catch (InvocationTargetException e) {
203       throw new MarshallingException("Invalid property: " + e.toString());
204     }
205     catch (FileNotFoundException e) {
206       throw new MarshallingException("Invalid File: " + file + " " + e.toString());
207     }
208     catch (IOException e) {
209       throw new MarshallingException("Problem File: " + file + " " + e.toString());
210     }
211     
212   }
213   
214 }