Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / July 2006

Tip: Looking for answers? Try searching our database.

cleaning up some reflection / dynamic method invocation code

Thread view: 
Marc E - 19 Jul 2006 01:02 GMT
All,
 Greetings. Looking for some java smarties who can help me see what I'm
missing.

Basically, i've got an object with a bunch of setXXXX() methods, each of
which takes a single argument that could be an int, boolean, long, or
String.  I'm calling those setters dynamically by looping through a list of
properties to set.  I've got it working with a bit of lame hackery, but i
can't help thinking that it's gotta be easier and cleaner than this.

My gut tells me that the convertArg() method and subsequent use of it are
just really lame and probably aren't necessary, but i just don't know the
API well enough to use what java already has built in. So, if i'm right
about that...if anyone can help me clean up this ugliness...i'd be much
obliged.

Feel free to rip the code a new A-Hole.  Thanks.

/**** CODE STARTS HERE ****/

public class POLARunner implements OptimizerRunner {
   Map types = createClassMap();
   ApplicationContext context = AppManager.getContext();
   ProfilePropertiesDAO propdao;
   POLAOptimizerInterface optimizer;
   boolean throwOnUnknownMethod = true;

   public void optimize(String inputFile, String outputFile, int fileID)
throws Exception {
       String methodName = "";
       Class argTypeClass;
       Class tmp;
       Object objArg;
       String arg = "";
       Method dynamethod;

       //get the profile settings
       List<ProfileProperty> props = propdao.getProfileProperties(fileID);

       //for each setting, call the setter
       tmp = Class.forName(optimizer.getClass().getCanonicalName());

       for (ProfileProperty prop : props) {
           if(!prop.getPropertyValue().equalsIgnoreCase("off")){
               methodName = "set" + prop.getPropertyName();

               argTypeClass =
(Class)types.get(prop.getArgDataType());//getArgDataType() will return
strings like "String", "int", "boolean"

               try {
                   dynamethod = tmp.getMethod(methodName,new
Class[]{argTypeClass});
                   arg = prop.getPropertyValue();

                   // here's where it gets super lame....there's gotta be a
way to not have to do this
                   objArg = convertArg(arg,prop.getArgDataType());

                   System.out.println("calling setter " + methodName
                           + " with arg type " +
argTypeClass.getCanonicalName()
                           + " with value " + arg);
                   dynamethod.invoke(optimizer, new Object[]{objArg});
               } catch (Exception e) {
                   System.out.println("Method named " + methodName + " did
not exist");
                   if(throwOnUnknownMethod){
                       throw new Exception(e);
                   }
               }
           }
       }
       //.....the actual real work after the set calls is omitted....
   }

   private Map createClassMap(){
       Map<String,Class> classtypes = new HashMap<String,Class>();
       classtypes.put("string",String.class);
       classtypes.put("int",int.class);
       classtypes.put("long",long.class);
       classtypes.put("double", double.class);
       classtypes.put("boolean",boolean.class);
       return classtypes;
   }

   /**
    * My super  lame hacker jobby for getting around the
IllegalArgumentException
    * @param arg the argument to convert
    * @param type the type of the argument to convert to
    * @return
    */
   private Object convertArg(String arg, String type){
       Object returnval = arg;

       if(type.equals("boolean")){
           returnval = Boolean.valueOf(arg);
       }else if(type.equals("int")){
           returnval = Integer.valueOf(arg);
       }else if(type.equals("long")){
           returnval = Long.valueOf(arg);
       }else if(type.equals("double")){
           returnval = Double.valueOf(arg);
       }
       return returnval;
   }

}
Thomas Hawtin - 19 Jul 2006 01:54 GMT
> Basically, i've got an object with a bunch of setXXXX() methods, each of
> which takes a single argument that could be an int, boolean, long, or
> String.  I'm calling those setters dynamically by looping through a list of
> properties to set.  I've got it working with a bit of lame hackery, but i
> can't help thinking that it's gotta be easier and cleaner than this.

I'd probably use java.beans for this. I'd also use the class set method
(bean property) to work out what type the argument should be. You may
find java.beans.PropertyEditor.setAsText useful.

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Marc E - 19 Jul 2006 03:00 GMT
great, thanks a lot, Tom. I'll check it out.

>> Basically, i've got an object with a bunch of setXXXX() methods, each of
>> which takes a single argument that could be an int, boolean, long, or
[quoted text clipped - 8 lines]
>
> Tom Hawtin


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.