<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Passion Development &#187; Reflection</title>
	<atom:link href="http://www.passiondevelopment.com/category/java/reflection/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.passiondevelopment.com</link>
	<description>Java Developers in Dublin Ireland &#124;  It&#039;s what we love</description>
	<lastBuildDate>Thu, 08 May 2008 15:00:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Reflection Tip &#8211; Dynamically calling methods</title>
		<link>http://www.passiondevelopment.com/2006/04/04/reflection-tip-dynamically-calling-methods/</link>
		<comments>http://www.passiondevelopment.com/2006/04/04/reflection-tip-dynamically-calling-methods/#comments</comments>
		<pubDate>Tue, 04 Apr 2006 22:32:51 +0000</pubDate>
		<dc:creator>Stephen Downey</dc:creator>
				<category><![CDATA[Reflection]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.passiondevelopment.com/2006/04/04/reflection-tip-dynamically-calling-methods/</guid>
		<description><![CDATA[There are often times when you need to call a method but you do not know the name of the method until runtime.&#160; I came across this issue during my Thesis.&#160;&#160;&#160; Our problem was as follows: How do we dynamically map between an object type and a method in the sub class of PublishableServer that [...]]]></description>
			<content:encoded><![CDATA[<p>There are often times when you need to call a method but you do not know the name of the method until runtime.&nbsp; I came across this issue during my <a href="http://www.stephendowney.net/blog/research/" title="Published Data Protocol">Thesis</a>.&nbsp;&nbsp;&nbsp; Our problem was as follows: <br /><em><br />How do we dynamically map between an object type and a method in the sub class of PublishableServer that processes that type?</em> </p>
<p>Here is some background to the problem: <br />PublishableServer&nbsp;is an abstract class that can connects to our distributed system and receives requests for lists of PublishedData objects.&nbsp;A subclasses of PublishableServer&nbsp;must implement methods to process various PublishedData objects it receives. </p>
<div align="center" style="text-align: center"><img src="http://www.stephendowney.net/blog/wp-includes/images/research/Central-JDBCServerSm.jpg" border="0" alt="The Central Server Connecting to a JDBC sub server" title="The Central Server Connecting to a JDBC sub server" width="214" height="226" /></div>
<p>If we look at the JDBCServer illustrated above.&nbsp; This class must implement methods to search for PublishedData objects&nbsp;in the database that it is connected to.&nbsp; Each method must map between attributes of the <em>PublishedData</em> object and the columns in the database.&nbsp;&nbsp; As the <em>getPublishedList(PublishedData publishedData)</em> method of <em>PublishableServer</em>&nbsp;is called we must map this <em>publishedData</em> object to the correct method in the sub class.&nbsp;&nbsp; </p>
<p>One option could be to declare the methods as abstract in the PublishableServer class and then use the <em>instanceof</em> operator to select the correct method. </p>
<blockquote><p>&nbsp;&nbsp;&nbsp; public ArrayList getPublishedList(PublishedData publishedData)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (publishedData instanceof Student)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return getPublishedList((Student) publishedData);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (publishedData instanceof Course)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return getPublishedList((Course) publishedData);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new ArrayList(0);<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public abstract ArrayList getPublishedList(Course publishedCourse);<br />&nbsp;&nbsp;&nbsp; public abstract ArrayList getPublishedList(Student publishedStudent);</p>
</blockquote>
<p>The issue with using this approach is that we&nbsp;need to update the <em>PublishableServer</em> class every time a new type of <em>PublishedData</em> is added to the framework. All <em>PublishableServer</em> implementations would also have to implement all the search methods, even if they did not want to.</p>
<p>The solution to this issue is to use Reflection to dynamically call the methods in the sub class.&nbsp; To allow this, the methods in the subclass must have a known name.&nbsp; We prepend &quot;getPublished&quot; to the name of the <em>PublishedData</em> class that was passed to the&nbsp; <em>getPublishedList()</em> method.&nbsp; So all we need to do is get the name of the class that has been passed, append that to &quot;getPublished&quot; and we have the name of the method that implements that search.&nbsp; The publishedData object implements a mehtod called <em>getClassName()</em> that will return the name of a class without the package name.&nbsp; To create a method to search for <em>Student</em> objects we simple implement the following method in the <em>JDBCServer</em> class that extends <em>PublishableServer</em>.</p>
<blockquote><p>public ArrayList getPublishedStudent(PublishedData publishedData)</p></blockquote>
<p>The body of this method should implement a search for <em>Student</em> objects in the servers persistent store using the properties of the <em>Student</em> object passed to narrow the search results.</p>
<p>So how do we call this method once we have its name?</p>
<p>The <em>getClass()</em> method that all java objects inherit will return the runtime class of the current object.&nbsp; In our case when we call this method inside the <em>PublishableServer</em> class we will get the runtime class that extended our <em>PublishableServer</em> class. <br />The <em>Class</em> object contains a method called <em>getMethod()</em> which takes the name of the method and an array of Class objects which represents the list of parameters for the method.&nbsp; If the method does not exist a <em>NoSuchMethodException</em>&nbsp;is thrown.&nbsp; If this is thrown in our server we simple return an empty <em>ArrayList</em> as this server does implement that search.</p>
<p>If the method does exist then we call <em>invoke()</em> passing the current object and PublishedData parameter.&nbsp; This will dynamically call our method and return an <em>Object</em> class.&nbsp; We must cast this to an <em>ArrayList</em> and return it.&nbsp; The implementation of this can be seen below.</p>
<blockquote><p>&nbsp;&nbsp;&nbsp; public ArrayList getPublishedList(PublishedData publishedData)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ArrayList result = new ArrayList(0);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String className = publishedData.getClassName();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String methodName = &quot;getPublished&quot; + className;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class[] argTypes = new Class[]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { PublishedData.class };<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object[] args = new Object[]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { publishedData };<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method m = this.getClass().getMethod(methodName, argTypes);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = (ArrayList) m.invoke(this, args);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (NoSuchMethodException noSuchMethod)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.error(&quot;ERROR: &quot; + serverName<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + &quot; does not support searches of type: &quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + publishedData.getClass().getName());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.error(&quot;ERROR:&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+ this.getClass().getName()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+ &quot; needs to implement the follwing method to preform search:&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.error(&quot;public ArrayList &quot; + methodName<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + &quot;(PublishedData publishedData){&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.error(&quot;&nbsp; ArrayList result = new ArrayList();&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.error(&quot;&nbsp; //Preform Search&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.error(&quot;&nbsp; return result;&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.error(&quot;}&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (IllegalAccessException illegalAccess)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.error(serverName + &quot; Does not support searches of type&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + publishedData.getClass().getName(), illegalAccess);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (InvocationTargetException invocTarget)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.error(serverName + &quot; Does not support searches of type&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + publishedData.getClass().getName(), invocTarget);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Exception general)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.error(serverName + &quot; Does not support searches of type&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + publishedData.getClass().getName(), general);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return result;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.passiondevelopment.com/2006/04/04/reflection-tip-dynamically-calling-methods/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

