Commit in lcsim/src/org/lcsim/job on MAIN
JobControlManager.java+64-1151.37 -> 1.38
fix class loading weirdness by not using Java Beans; also simplifies method-finding logic

lcsim/src/org/lcsim/job
JobControlManager.java 1.37 -> 1.38
diff -u -r1.37 -r1.38
--- JobControlManager.java	17 May 2010 18:13:56 -0000	1.37
+++ JobControlManager.java	17 May 2010 21:26:20 -0000	1.38
@@ -1,8 +1,5 @@
 package org.lcsim.job;
 
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.MethodDescriptor;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
@@ -42,26 +39,14 @@
 import org.lcsim.util.loop.LCSimLoop;
 import org.lcsim.util.xml.ClasspathEntityResolver;
 import org.lcsim.util.xml.JDOMExpressionFactory;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
 
 /**
  * The <code>JobControlManager</code> provides an XML frontend for running LCSim jobs.
  * The command line syntax is <code>java -jar ./lib/lcsim.jar steeringFile.xml</code>.
+ * 
  * @author jeremym
  * @verbose $id: $
  */
-// TODO: Additional input parameter types (SymmetricMatrix, etc.).
-// TODO: Example XML steering file generation (e.g. like Marlin).
-// TODO: Basic command line argument support:
-//      -s steeringFile
-//      -e exampleSteeringOutput.xml
-//      -d debug only; don't actually run the job.
-//      etc.
-// TODO: Allow input data files to be specified from command-line.
-// TODO: Implement some kind of auto-naming output scheme, 
-//       possibly with a new Driver extending LCIODriver.
 public class JobControlManager
 {
 	Map<String, Driver> driverMap;
@@ -135,10 +120,7 @@
 			(new LCSimVersion()).printOut(logStream);			
 			logStream.println();
 		}
-		
-		if (printSystemProperties)
-			printSystemProperties(logStream);
-		
+				
 		// Add the drivers to the loop.
 		for (Driver driver : driverExec)
 		{
@@ -279,22 +261,26 @@
 	{		
 		// Clear data structures in case a previous job was run.
 		clear();
-
+		
 		// Set the root element.
 		root = doc.getRootElement();
-		
-		// Setup units.
-		setupUnits();
-		
-		// Process the variable definitions.
-		processConstants();
-
+				
 		// Setup the job control parameters.
 		setupJobControlParameters();
+
+		// Print system properties.
+	    if (printSystemProperties)
+	            printSystemProperties(logStream);
 		
 		// Setup the class loader.
 		setupClassLoader();
+	
+		// Setup units.
+        setupUnits();
 		
+        // Process the variable definitions.
+        processConstants();     
+				
 		// Setup drivers with parameters and execution order.
 		setupDrivers();
 
@@ -764,7 +750,7 @@
 			}
 			logStream.println("-- End Extra Classpath URLs --");
 			logStream.println();
-		}		
+		}				
 	}
 	
 	private void setupFileCache()
@@ -821,18 +807,7 @@
 			
 			if (printDriversDetailed)
 				logStream.println(driverClass.getCanonicalName());
-			
-			// BeanInfo for the Driver class.
-			BeanInfo beaninfo;
-			try 
-			{
-				beaninfo = java.beans.Introspector.getBeanInfo(driverClass);
-			}
-			catch (IntrospectionException x)
-			{
-				throw new RuntimeException("Problem loading BeanInfo for Driver class " + type + ".");
-			}
-			
+									
 			// The Driver instance.
 			Driver newDriver;
 			try 
@@ -865,64 +840,41 @@
 				
 				// Get the parameter name.
 				String pname = parameterElement.getName();
-
-				// Manually create a list of methods that might be associated with this parameter.
-				List<MethodDescriptor> methList = new ArrayList<MethodDescriptor>();
-				for (MethodDescriptor meth : beaninfo.getMethodDescriptors())
-				{
-					if (meth.getName().startsWith("set"))
-					{
-						String propHack = meth.getName().replace("set", "");
-						propHack = propHack.substring(0, 1).toLowerCase() + propHack.substring(1);
-						if (propHack.equals(pname))
-						{
-							methList.add(meth);
-						}
-					}						
-				}
+			
+				//Method methods[] = driverClass.getDeclaredMethods();
+				List<Method> methods = getSetterMethods(driverClass);
+				List<Method> methodCandidates = new ArrayList<Method>();
+				for (Method method : methods)
+                {				   				   
+                    String propHack = method.getName().replace("set", "");
+                    propHack = propHack.substring(0, 1).toLowerCase() + propHack.substring(1);
+                    if (propHack.equals(pname))
+                    {
+                        methodCandidates.add(method);
+                    }
+                }
 				
-				// No method was found, so we need to bail out of the job.
-				if (methList.size() == 0)
-				{
-					throw new RuntimeException("No set method was found for parameter " + pname + " in Driver " + name + ".");
-				}				
-				// In this case, need to figure out which overloaded method to use.
-				else if (methList.size() > 1)
+				// Found it!
+				if (methodCandidates.size() == 1)
+                {
+				    setter = methodCandidates.get(0);
+				    if (setter.getParameterTypes().length > 1)
+				    {
+				        throw new RuntimeException("The set method has too many arguments for parameter: " + pname);
+				    }
+                    propertyType = setter.getParameterTypes()[0];
+                }
+				// No method found.  Parameter name is probably wrong.  
+				else if (methodCandidates.size() == 0)
 				{
-					if (parameterElement.getAttribute("type") == null)
-						throw new RuntimeException("Parameter " + pname + " in Driver " + driverClass.getCanonicalName() 
-								+ " is overloaded, but a type field is missing from the parameter's XML element.");
-					try 
-					{
-						// Try a primitive type first.
-						propertyType = getPrimitiveType(parameterElement.getAttribute("type").getValue());
-						
-						// If type is null, then parameter is an Object and not a primitive, or it is not a valid type.
-						if (propertyType == null)
-							propertyType = Class.forName(parameterElement.getAttribute("type").getValue());
-					}
-					catch (ClassNotFoundException x)
-					{						
-						throw new RuntimeException("Bad user type " + parameterElement.getAttribute("type").getValue() + " for parameter " + pname + ".");
-					}
-					// Find a method that matches the user type.
-					for (MethodDescriptor meth : methList)
-					{
-						Method m = meth.getMethod();
-						if (m.getParameterTypes().length == 1 && m.getParameterTypes()[0].equals(propertyType))
-						{
-							setter = meth.getMethod();
-							break;
-						}						
-					}
+				    throw new RuntimeException("No set method found for parameter: " + pname);
 				}
-				// Use the single method that was found.
-				else if (methList.size() == 1)
+				// Overloaded method.  Don't bother trying to disambiguate.  Just throw an error.
+				else if (methodCandidates.size() > 1)
 				{
-					setter = methList.get(0).getMethod();
-					propertyType = setter.getParameterTypes()[0];
-				}														
-								
+				    throw new RuntimeException("Multiple set methods found for parameter: " + pname);
+				}			
+				
 				IParameterConverter converter = paramConverter.getConverterForType(propertyType);
 				if (converter == null)
 				{
@@ -1009,25 +961,22 @@
 		if (name.equals("String")) return String.class;
 		return null;
 	}		
-}
-
-/**
- * Setup a list of available Drivers if a services file exists.
- */
-/*
-private void findAvailableDrivers()
-{
-	InputStream in = JobControlManager.class.getResourceAsStream("/META-INF/services/org.lcsim.util.Driver");
-	if (in == null)
-	{			
-		return;
-	}
-	Scanner scan = new Scanner(in);
-	while (scan.hasNext())
+	
+	public List<Method> getSetterMethods(Class klass)
 	{
-		String fullName = scan.nextLine().trim();
-		String shortName = fullName.substring(fullName.lastIndexOf(".") + 1);
-		availableDrivers.put(shortName, fullName);
+	    List<Method> methods = new ArrayList<Method>();
+	    Class currentClass = klass;
+	    while (currentClass != null)
+	    {
+	        for (Method method : currentClass.getMethods())
+	        {
+	            if (method.getName().startsWith("set") && !methods.contains(method))
+	            {
+	                methods.add(method);
+	            }
+	        }
+	        currentClass = currentClass.getSuperclass();
+	    }
+	    return methods;
 	}
-}
-*/
+}
\ No newline at end of file
CVSspam 0.2.8