<?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>Brim &#187; Java</title>
	<atom:link href="http://www.brimllc.com/category/blog/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.brimllc.com</link>
	<description>streamlined software development</description>
	<lastBuildDate>Tue, 31 Jan 2012 23:30:48 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Grails &#8211; groovy.lang.MissingPropertyException: No such property: name for class:  java.lang.Object</title>
		<link>http://www.brimllc.com/2012/01/grails-groovy-lang-missingpropertyexception-no-such-property-name-for-class-java-lang-object/</link>
		<comments>http://www.brimllc.com/2012/01/grails-groovy-lang-missingpropertyexception-no-such-property-name-for-class-java-lang-object/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 23:29:24 +0000</pubDate>
		<dc:creator>tmillhouse</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.brimllc.com/?p=458</guid>
		<description><![CDATA[After adding a custom Comparator to sort one of my domain models, I started getting the following exception sporadically:
groovy.lang.MissingPropertyException: No such property: name for class:
java.lang.Object
The odd thing is that the model I was attempting to sort was one of my domain models of type Transaction; however, grails was interpreting it as a generic Object. The [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>After adding a custom Comparator to sort one of my domain models, I started getting the following exception sporadically:</p>
<p>groovy.lang.MissingPropertyException: No such property: name for class:<br />
java.lang.Object</p>
<p>The odd thing is that the model I was attempting to sort was one of my domain models of type Transaction; however, grails was interpreting it as a generic Object. The really weird thing is that it was also interpreting my Transaction objects as generic Objects in other locations as well. After a while of debugging, I went back to the code where I started seeing the issue. I had created a private inner class for the Comparator and defined it as follows:</p>
<p><code><br />
private class TransactionComparator&lt;Transaction&gt; extends Comparator&lt;Transaction&gt;</p>
<p>...<br />
</code></p>
<p>My mistake was including the generic declaration at the class level. This would be invalid in normal Java syntax; however, groovy was compiling another class named Transaction, but it was casting it to a generic Object. Once I fixed my class to the following, the issue went away:</p>
<p><code><br />
private class TransactionComparator extends Comparator&lt;Transaction&gt;</p>
<p>...<br />
</code></p>
<p>I hope this helps others that run into similar issues.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.brimllc.com/2012/01/grails-groovy-lang-missingpropertyexception-no-such-property-name-for-class-java-lang-object/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grails &#8211; CXF Web Service with MTOM Attachments</title>
		<link>http://www.brimllc.com/2012/01/grails-cxf-web-service-with-mtom-attachments/</link>
		<comments>http://www.brimllc.com/2012/01/grails-cxf-web-service-with-mtom-attachments/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 19:24:58 +0000</pubDate>
		<dc:creator>tmillhouse</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.brimllc.com/?p=456</guid>
		<description><![CDATA[I&#8217;m writing this mostly for my own reference, but I thought it would be helpful to others as well. I&#8217;ve been working a lot lately with integrating CXF into grails via the CXF-grails plugin; however, while enabling MTOM to allow SOAP attachments, I ran into a few issues that I had to work around. The [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I&#8217;m writing this mostly for my own reference, but I thought it would be helpful to others as well. I&#8217;ve been working a lot lately with integrating CXF into grails via the CXF-grails plugin; however, while enabling MTOM to allow SOAP attachments, I ran into a few issues that I had to work around. The following are the steps I took to successfully allow uploading files via my web service:</p>
<h2>1. Enable MTOM on the service</h2>
<p><code><br />
	@MTOM(enabled = true)<br />
	@javax.jws.WebService(<br />
	serviceName = "MyWebService",<br />
	portName = "MyWebService",<br />
	targetNamespace = "http://test.brimllc.com",<br />
	endpointInterface = "com.brimllc.ws.MyWebServiceInterface")<br />
	class MyWebService ...<br />
</code></p>
<h2>2. Add the MIME type to the DataHandler request object.</h2>
<p>This step allows the binding of the incoming attachment to the bean field.</p>
<p><code><br />
	// ... some request bean<br />
	@XmlMimeType("application/octet-stream")<br />
	private DataHandler fileData;<br />
</code></p>
<h2>3. Exclude the &#8216;/services&#8217; path from UrlMappings.groovy. </h2>
<p>Without this step, the default grails URL interceptor will process the request as a file upload, which in turn will read the InputStream, causing the CXF interceptor to have an empty stream.</p>
<p><code><br />
	static excludes = ['/services*']<br />
</code></p>
<h2>4. Remove mail.jar &#038; activation.jar from the classpath in BuildConfig.groovy</h2>
<p>My project is using the mail plugin, which manually copies over these jars from it&#8217;s /lib folder. One of the CXF interceptors will throw an error since the classes contained within these jars has already been loaded by the servlet containers classpath.</p>
<p><code><br />
	grails.war.resources = { stagingDir, args -><br />
		println "Removing mail.jar and activation.jar from WEB-INF/lib/"<br />
		delete(file: "${stagingDir}/WEB-INF/lib/mail.jar")<br />
		delete(file: "${stagingDir}/WEB-INF/lib/activation.jar")<br />
	}<br />
</code></p>
<p>Now, your grails-cxf web service should be able to properly process an incoming MTOM SOAP message. One thing to note is that you may need to extend and modify the LoggingInInterceptor since it doesn&#8217;t know how to properly log the incoming messages with multiple boundaries. I can provide examples of this as well if anyone is interested. I&#8217;ve tested my service using SoapUI as a SOAP client. SoapUI allows you to specify MTOM settings on your test requests as well as adding attachments.</p>
<p>I&#8217;ve done a lot more work with Grails-CXF integration, so if there are other topics that anyone is interested in, email me and let me know. (devs@brimllc.com)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.brimllc.com/2012/01/grails-cxf-web-service-with-mtom-attachments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache CXF Client- Setting Http Request Header for Basic Authentication</title>
		<link>http://www.brimllc.com/2011/04/apache-cxf-client-setting-http-request-header-for-basic-authentication/</link>
		<comments>http://www.brimllc.com/2011/04/apache-cxf-client-setting-http-request-header-for-basic-authentication/#comments</comments>
		<pubDate>Wed, 27 Apr 2011 18:55:54 +0000</pubDate>
		<dc:creator>Yagish Sharma</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.brimllc.com/?p=436</guid>
		<description><![CDATA[While setting up Test Driven Development environment with Apache CXF, I came across a small issue with creating a JUnit client, which will add the Basic Authentication info in the Http Request Header before sending the request. I found couple of ways to do this using JAXWS, but wanted to stick with Apache CXF.
 On [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>While setting up Test Driven Development environment with Apache CXF, I came across a small issue with creating a JUnit client, which will add the Basic Authentication info in the Http Request Header before sending the request. I found couple of ways to do this using <a href="http://www.mkyong.com/webservices/jax-ws/application-authentication-with-jax-ws/">JAXWS</a>, but wanted to stick with Apache CXF.<br />
 On the Server side, I was using Spring Security which was not so tricky to configure. To add the header info, I needed to create an &#8220;Interceptor&#8221;, which will intercept the message before it is &#8220;marshalled&#8221;. Here is the code -</p>
<pre>
 <code>
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.Phase;
import org.springframework.beans.factory.annotation.Required;
 public class BasicAuthenticationHeaderGeneratorInterceptor extends
		AbstractOutDatabindingInterceptor {
	public static final String COLON = ":";
	public static final String SPACE = " ";
	public static final String BASIC = "Basic";
	/** Map of allowed users to this system with their corresponding passwords. */
	private Map users;

	@Required
	public void setUsers(Map users) {
		this.users = users;
	}

	public BasicAuthenticationHeaderGeneratorInterceptor() {
		super(Phase.MARSHAL);
	}

	public BasicAuthenticationHeaderGeneratorInterceptor(String phase) {
		super(phase);
	}

	public void handleMessage(Message outMessage) throws Fault {
		Map&lt;String, List&gt; headers = (Map&lt;String, List&gt;) outMessage
				.get(Message.PROTOCOL_HEADERS);
		try {
			headers.put("Authorization", Collections.singletonList(BASIC
					+ SPACE + getBase64EncodedCredentials().trim()));
		} catch (Exception ce) {
			throw new Fault(ce);
		}
	}

	private String getBase64EncodedCredentials(){
		String userName = null;
		String password = null;
		Iterator iterator = null != users ? users.keySet().iterator()
				: null;
		if (null != iterator &amp;&amp; iterator.hasNext()) {
			userName = iterator.next();
			password = users.get(userName);
		}
		String clearCredentials = userName + COLON + password;
		return new String(Base64.encodeBase64(clearCredentials.getBytes()));
	}
}
</code>
</pre>
<p>Here is the interceptor configuration in application-context.xml -</p>
<pre>
 <code>
  &lt;cxf:bus&gt;
		&lt;cxf:outInterceptors&gt;
			&lt;ref bean="basicAuthenticationHeaderGenerator" /&gt;
		&lt;/cxf:outInterceptors&gt;
  &lt;/cxf:bus&gt;

  &lt;bean id="basicAuthenticationHeaderGenerator"
	class="com.blah.interceptor.BasicAuthenticationHeaderGeneratorInterceptor"&gt;
		&lt;property name="users"&gt;
			&lt;map&gt;
				&lt;entry key="abc" value="dev" /&gt;
			&lt;/map&gt;
		&lt;/property&gt;
	&lt;/bean&gt;
</code>
</pre>
<p> I preferred this implementation over JAXWS, since it works great with Spring Test and Apache CXF, without having to use JAXWS API. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.brimllc.com/2011/04/apache-cxf-client-setting-http-request-header-for-basic-authentication/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>a4j:jsFunction in IE6/7 breaks when html:form&#8217;s prependId=&#8221;false&#8221;</title>
		<link>http://www.brimllc.com/2011/04/a4jjsfunction-in-ie67-breaks-when-htmlforms-prependidfalse/</link>
		<comments>http://www.brimllc.com/2011/04/a4jjsfunction-in-ie67-breaks-when-htmlforms-prependidfalse/#comments</comments>
		<pubDate>Thu, 21 Apr 2011 18:36:01 +0000</pubDate>
		<dc:creator>Yagish Sharma</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.brimllc.com/?p=424</guid>
		<description><![CDATA[I wrote this article in JBoss Community. Here is another version of the same article. It is useful, when porting existing application from Ajax4JSF to use RichFaces.
In RichFaces3.2.2SR1, a4j:jsFunction generates an HTML script, which breaks in IE6/7, but works in FireFox. The issue is the way the jsFunction is rendered.
Here is a sample of how [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I wrote this article in <a href="http://community.jboss.org/thread/13631">JBoss Community</a>. Here is another version of the same article. It is useful, when porting existing application from Ajax4JSF to use RichFaces.</p>
<p>In RichFaces3.2.2SR1, a4j:jsFunction generates an HTML script, which breaks in IE6/7, but works in FireFox. The issue is the way the jsFunction is rendered.</p>
<p>Here is a sample of how the script is rendered in Ajax4JSF and in RichFaces when html:form&#8217;s prependId attribute is false.</p>
<p>Notice that the name and id fields are kept same.</p>
<p>In Ajax4JSF, this will render as -</p>
<pre><code>
script id="func1" type="text/javascript"
function func1(){.........};
/script
</code></pre>
<p>In RichFaces, this renders as -</p>
<pre><code>
script id="func1" type="text/javascript"&gt;
func1 = function(){.........};
/script
</code></pre>
<p>Having the &#8220;id&#8221; of script tag and the func1 prototype &#8220;name&#8221; as same creates the problem. IE6/7 while parsing the script tag gives an error &#8211; &#8220;Object does not supports this property&#8221;.</p>
<p>In RichFaces the renderer for jsFunction is AjaxFunctionRendererBase. This renderer&#8217;s getFunction() method has changed from Ajax4JSF and generates this inappropriate javascript code.</p>
<p>A simple fix would be to set html:form&#8217;s prependId=&#8221;true&#8221;, which will append the form&#8217;s name to the &#8220;id&#8221; attribute, and the name and id will be different. There is a catch, in an existing application, then u will have to change all the javascript which uses the &#8220;id&#8221; to find the element. </p>
<p>The real fix would be to change the AjaxFunctionRenderer of RichFaces. Actually, its more like a workaround. If you are creating a new application from scratch, and using RichFaces, i will still use the RichFaces version.<br />
Here is how to do it -<br />
Create a new class extending the FunctionRenderer in RichFaces, and over-ride the getFunction method -</p>
<pre><code>
public class NewAjaxFunctionRenderer extends FunctionRenderer{
 /*
 * (non-Javadoc)
 *
 * @see org.ajax4jsf.framework.renderer.RendererBase#getComponentClass()
 */

 public static final String RENDERER_TYPE = "org.abc.AjaxFunctionRenderer";
 protected Class getComponentClass() {
 return HtmlAjaxFunction.class;
 }

 public String getFunction(FacesContext context, UIAjaxFunction component) {
 StringBuffer script = new StringBuffer();
 JSFunctionDefinition func = new JSFunctionDefinition();
 func.setName(component.getName());
 // Create AJAX Submit function.
 JSFunction ajaxFunction = AjaxRendererUtils.buildAjaxFunction(
 component, context,AjaxRendererUtils.AJAX_FUNCTION_NAME);
 Map options = AjaxRendererUtils.buildEventOptions(context, component);
 Map parameters = (Map) options.get("parameters");
 if (null == parameters) {
 parameters = new HashMap();
 options.put("parameters", parameters);
 }
 ajaxFunction.addParameter(JSReference.NULL);
 ajaxFunction.addParameter(options);
 // Fill parameters.
 for (Iterator it = component.getChildren().iterator(); it.hasNext();) {
 UIComponent child = (UIComponent) it.next();
 if (child instanceof UIParameter) {
 UIParameter parameter = ((UIParameter) child);
 String name = parameter.getName();
 func.addParameter(name);
 // Put parameter name to AJAX.Submit parameter, with default value.
 JSReference reference = new JSReference(name);
 if (null != parameter.getValue()) {
 reference = new JSReference(name + "||"
 + ScriptUtils.toScript(parameters.get(name)));

 }
 // Replace parameter value to reference.
 parameters.put(name, reference);
 }
 }
 func.addToBody(ajaxFunction.toScript());
 func.appendScript(script);
 return script.toString();
 }
}
</code></pre>
<p>In faces-config.xml add the new renderer for a4j:jsFunction &#8211; </p>
<pre><code>

 &lt;renderer&gt;
 &lt;component-family&gt;org.ajax4jsf.components.AjaxFunction&lt;/component-family&gt;
 &lt;renderer-type&gt;
 org.ajax4jsf.components.AjaxFunctionRenderer
 &lt;/renderer-type&gt;
 &lt;renderer-class&gt;
 org.test.NewAjaxFunctionRenderer
 &lt;/renderer-class&gt;
 &lt;/renderer&gt;

</code></pre>
<p> The tricky part is to find the component-family and renderer-type for AjaxFunctionRenderer. You can explode the richfaces jar and search the faces-config.xml to look for component-family and renderer-type for AjaxFunctionRenderer. Once you have it, this can be easily over-ridden in your application&#8217;s faces-config.xml as listed above.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.brimllc.com/2011/04/a4jjsfunction-in-ie67-breaks-when-htmlforms-prependidfalse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Groovy Google Chart Encoding Script</title>
		<link>http://www.brimllc.com/2011/01/groovy-google-chart-encoding-script/</link>
		<comments>http://www.brimllc.com/2011/01/groovy-google-chart-encoding-script/#comments</comments>
		<pubDate>Sun, 23 Jan 2011 19:02:00 +0000</pubDate>
		<dc:creator>tmillhouse</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Grails]]></category>

		<guid isPermaLink="false">http://www.brimllc.com/?p=394</guid>
		<description><![CDATA[I&#8217;ve been playing around with Google Chart integration into a new Grails application, and while teaching myself the chart data formats, I converted the javascript data encoding script to Groovy. This hasn&#8217;t been tested thoroughly, but its been working nicely for me in my project.

/**
 * See http://code.google.com/apis/chart/docs/data_formats.html#extended
 */
class GoogleChartUtil {
	private static final String simpleEncoding [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I&#8217;ve been playing around with Google Chart integration into a new Grails application, and while teaching myself the chart data formats, I converted the <a href="http://code.google.com/apis/chart/docs/data_formats.html">javascript data encoding script</a> to Groovy. This hasn&#8217;t been tested thoroughly, but its been working nicely for me in my project.</p>
<p><code><br />
/**<br />
 * See http://code.google.com/apis/chart/docs/data_formats.html#extended<br />
 */<br />
class GoogleChartUtil {</p>
<p>	private static final String simpleEncoding = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';</p>
<p>	// This function scales the submitted values so that<br />
	// maxVal becomes the highest value.<br />
	static simpleEncode(valueArray,maxValue) {<br />
		def chartData = ['s:'];<br />
		for (int i = 0; i < valueArray.size(); i++) {<br />
			def currentValue = valueArray[i];<br />
			if (currentValue >= 0) {<br />
				chartData.push(simpleEncoding.charAt((int) Math.round((simpleEncoding.length()-1) *<br />
						currentValue / maxValue)));<br />
			}<br />
			else {<br />
				chartData.push('_');<br />
			}<br />
		}<br />
		return chartData.join('');<br />
	}</p>
<p>	private static final String EXTENDED_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.';<br />
	private static final int EXTENDED_MAP_LENGTH = EXTENDED_MAP.length();</p>
<p>	static extendedEncode(arrVals, maxVal) {<br />
		def chartData = 'e:';</p>
<p>		int len = arrVals.size();<br />
		for(int i = 0; i < len; i++) {<br />
			// In case the array vals were translated to strings.<br />
			def numericVal = new Float(arrVals[i]);<br />
			// Scale the value to maxVal.<br />
			def scaledVal = Math.floor(EXTENDED_MAP_LENGTH *<br />
					EXTENDED_MAP_LENGTH * numericVal / maxVal);</p>
<p>			if(scaledVal > (EXTENDED_MAP_LENGTH * EXTENDED_MAP_LENGTH) - 1) {<br />
				chartData += "..";<br />
			} else if (scaledVal < 0) {<br />
				chartData += '__';<br />
			} else {<br />
				// Calculate first and second digits and add them to the output.<br />
				def quotient = Math.floor(scaledVal / EXTENDED_MAP_LENGTH);<br />
				def remainder = scaledVal - EXTENDED_MAP_LENGTH * quotient;<br />
				chartData += EXTENDED_MAP.charAt((int)quotient) + EXTENDED_MAP.charAt((int)remainder);<br />
			}<br />
		}</p>
<p>		return chartData;<br />
	}<br />
}<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.brimllc.com/2011/01/groovy-google-chart-encoding-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GRAILS: Execute Raw/Native SQL Queries</title>
		<link>http://www.brimllc.com/2011/01/grails-execute-rawnative-sql-queries/</link>
		<comments>http://www.brimllc.com/2011/01/grails-execute-rawnative-sql-queries/#comments</comments>
		<pubDate>Sat, 15 Jan 2011 19:30:46 +0000</pubDate>
		<dc:creator>tmillhouse</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.brimllc.com/?p=388</guid>
		<description><![CDATA[Although Grails provides a great abstraction on top of hibernate (GORM), it is sometimes necessary to execute raw SQL against the configured data source. An example of when you might want to do this is when you&#8217;d like to execute a query with computed values for reporting purposes. 
For example, say you have an &#8220;events&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>Although Grails provides a great abstraction on top of hibernate (GORM), it is sometimes necessary to execute raw SQL against the configured data source. An example of when you might want to do this is when you&#8217;d like to execute a query with computed values for reporting purposes. </p>
<p>For example, say you have an &#8220;events&#8221; table, and you&#8217;d like to chart how many events were created grouped by the entry dates. You could have SQL like such:</p>
<p><code><br />
select substring(event.data_created, 1, 10) as dateCreated, count(event.id) from event where event.date_created > ? group by dateCreated order by event.date_created;<br />
</code></p>
<p>With the above query, you&#8217;ll retrieve the amount of events grouped by the day they occurred. Since you&#8217;re not binding this return data to any entity, its easier (and in my opinion cleaner), to execute this query apart from any hibernate approach (such as a named query). </p>
<p>In your service, define the following:</p>
<p><code><br />
def sessionFactory;<br />
</code></p>
<p>This line will ensure grails will inject the configured hibernate session factory into your service. Now, within your service method, you could write code as such:</p>
<p><code><br />
Session session = sessionFactory.openSession();<br />
		session.doWork new Work() {<br />
					@Override<br />
					public void execute(Connection conn) throws SQLException {<br />
						// execute your statement against the connection<br />
					}<br />
				};<br />
</code></p>
<p>Let me know if you have any better ideas&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.brimllc.com/2011/01/grails-execute-rawnative-sql-queries/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Selenium 2.0 / Webdriver extending FindBy annotation to support dynamic id/xpath</title>
		<link>http://www.brimllc.com/2011/01/selenium-2-0-webdriver-extending-findby-annotation-to-support-dynamic-idxpath/</link>
		<comments>http://www.brimllc.com/2011/01/selenium-2-0-webdriver-extending-findby-annotation-to-support-dynamic-idxpath/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 18:09:49 +0000</pubDate>
		<dc:creator>Yagish Sharma</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.brimllc.com/?p=358</guid>
		<description><![CDATA[In my previous article, I suggested ways to extend Selenium 2.0 to support Ajax reliably. 
 While working with Selenium 2.0, I really liked usage of FindBy annotations, its concise and pretty cool. Reduces the code by tons of lines, when used with PageFactory. While writing my test cases, I hit a functionality, where I [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>In my <a href="http://www.brimllc.com/2011/01/extending-selenium-2-0-webdriver-to-support-ajax/">previous article</a>, I suggested ways to extend Selenium 2.0 to support Ajax reliably. </p>
<p> While working with Selenium 2.0, I really liked usage of FindBy annotations, its concise and pretty cool. Reduces the code by tons of lines, when used with PageFactory. While writing my test cases, I hit a functionality, where I click a link, which makes an ajax call and adds a new row in the table. The only change in the id / name/ xpath was the index of the item (calling it item, thanks to working with JSF and Wicket, I think in UI components). </p>
<p> Since FindBy annotations only take static strings for id / name / xpath, due to the nature of Java annotations, I didn&#8217;t wanted to fallback to using WebDriver.findElement api. So, I extended Selenium&#8217;s / WebDriver&#8217;s FindBy annotation processor. God Bless Open Source <img src='http://www.brimllc.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p> Some of the code, I am going to reuse is present in my <a href="http://www.brimllc.com/2011/01/extending-selenium-2-0-webdriver-to-support-ajax/">previous article</a>. Here is how to do it.</p>
<p> Since what I need is a new ElementLocator, so I will start creating that first, next will show how to expose it to be used by a Page Object. The magic happens in AnnotationsAcceptingIndex private class. The code is self explanatory. Excuse for some copy/paste and code smell. This class extends the Selenium&#8217;s Annotations class, which handles the FindBy and FindBys annotations, checks the using attribute of FindBy annotation and replace the # sign with the index. Pretty easy. eh!!</p>
<pre>
 <code>
		package com.brim.selenium.locator;

		import java.lang.reflect.Field;

		import org.apache.commons.lang.StringUtils;
		import org.openqa.selenium.By;
		import org.openqa.selenium.NoSuchElementException;
		import org.openqa.selenium.RenderedWebElement;
		import org.openqa.selenium.WebDriver;
		import org.openqa.selenium.WebElement;
		import org.openqa.selenium.support.ByIdOrName;
		import org.openqa.selenium.support.FindBy;
		import org.openqa.selenium.support.How;
		import org.openqa.selenium.support.pagefactory.AjaxElementLocator;
		import org.openqa.selenium.support.pagefactory.Annotations;
		import org.openqa.selenium.support.ui.Clock;
		import org.openqa.selenium.support.ui.SlowLoadableComponent;
		import org.openqa.selenium.support.ui.SystemClock;

		public class AjaxListItemLocator extends AjaxElementLocator {

			protected final int timeOutInSeconds;
			private Clock clock;
			private WebDriver driver;
			private Field field;
			// the only thing that is differnt from AjaxElementLocator
			// the index to replace.
			private int index;

			public AjaxListItemLocator(WebDriver driver, Field field, int index,
					int timeOutInSeconds) {
				this(((Clock) (new SystemClock())), driver, field, timeOutInSeconds);
				this.driver = driver;
				this.field = field;
				this.index = index;
			}

			private AjaxListItemLocator(Clock clock, WebDriver driver, Field field,
					int timeOutInSeconds) {
				super(clock, driver, field, timeOutInSeconds);
				this.timeOutInSeconds = timeOutInSeconds;
				this.clock = clock;
			}

			public WebElement findElement() {
				SlowLoadingElement loadingElement = new SlowLoadingElement(clock,
						timeOutInSeconds);
				try {
					return loadingElement.get().getElement();
				} catch (NoSuchElementError e) {
					throw new NoSuchElementException(String.format(
							"Timed out after %d seconds. %s", timeOutInSeconds, e
									.getMessage()), e.getCause());
				}
			}

			protected long sleepFor() {
				return timeOutInSeconds;
			}

			private class SlowLoadingElement extends
					SlowLoadableComponent {
				private NoSuchElementException lastException;
				private WebElement element;
				private By by;

				public SlowLoadingElement(Clock clock, int timeOutInSeconds) {
					super(clock, timeOutInSeconds);
				}

				// here is the magic, AnnotationsAcceptingIndex class excepts the field, and also the index
				protected void load() {
					AnnotationsAcceptingIndex annotations = new AnnotationsAcceptingIndex(
							AjaxListItemLocator.this.field,
							AjaxListItemLocator.this.index);
					by = annotations.buildBy();
					this.element = AjaxListItemLocator.this.driver.findElement(by);
					this.element.isEnabled();
				}

				protected long sleepFor() {
					return AjaxListItemLocator.this.sleepFor();
				}

				protected void isLoaded() throws Error {
					try {
						load();
						if (!isElementUsable(element)) {
							throw new NoSuchElementException("Element is not usable");
						}
					} catch (NoSuchElementException e) {
						lastException = e;
						// Should use JUnit's AssertionError, but it may not be present
						throw new NoSuchElementError("Unable to locate the element", e);
					}
				}

				protected boolean isElementUsable(WebElement element) {
					try {
						return ((RenderedWebElement) element).isDisplayed();
					} catch (Exception ex) {

					}
					return false;
				}

				public NoSuchElementException getLastException() {
					return lastException;
				}

				public WebElement getElement() {
					return element;
				}
			}

            // This class sees the FindBy annotation's using clause and replace the # sign with the index.
            // extends the org.openqa.selenium.support.pagefactory.Annotations class
			private static class AnnotationsAcceptingIndex extends Annotations {
				private int index;
				private Field field;

				public AnnotationsAcceptingIndex(Field field, int index) {
					super(field);
					this.field = field;
					this.index = index;
				}
                // replace the # with the index
				private String getId(String idPrefix, int index) {
					return StringUtils.replace(idPrefix, "#", String.valueOf(index));
				}

				protected By buildByFromLongFindBy(FindBy findBy) {
					How how = findBy.how();
					// get the using attribute
					String using = findBy.using();
					// now replace the # sign with index
					using = getId(using, this.index);
					switch (how) {
					case CLASS_NAME:
						return By.className(using);

					case ID:
						return By.id(using);

					case ID_OR_NAME:
						return new ByIdOrName(using);

					case LINK_TEXT:
						return By.linkText(using);

					case NAME:
						return By.name(using);

					case PARTIAL_LINK_TEXT:
						return By.partialLinkText(using);

					case TAG_NAME:
						return By.tagName(using);

					case XPATH:
						return By.xpath(using);

					default:
						// Note that this shouldn't happen (eg, the above matches all
						// possible values for the How enum)
						throw new IllegalArgumentException(
								"Cannot determine how to locate element " + field);
					}
				}

				protected By buildByFromShortFindBy(FindBy findBy) {
					if (!"".equals(findBy.className()))
						return By.className(findBy.className());

					if (!"".equals(findBy.id()))
						return By.id(getId(findBy.id(), this.index));

					if (!"".equals(findBy.linkText()))
						return By.linkText(findBy.linkText());

					if (!"".equals(findBy.name()))
						return By.name(getId(findBy.name(), this.index));

					if (!"".equals(findBy.partialLinkText()))
						return By.partialLinkText(findBy.partialLinkText());

					if (!"".equals(findBy.tagName()))
						return By.tagName(findBy.tagName());

					if (!"".equals(findBy.xpath()))
						return By.xpath(getId(findBy.xpath(), this.index));

					// Fall through
					return null;
				}

			}

			private static class NoSuchElementError extends Error {
				private NoSuchElementError(String message, Throwable throwable) {
					super(message, throwable);
				}
			}

		}

 </code>
</pre>
<p> Now we have the element locator, lets now create a factory which extends the Ajax supporting factory, defined in my <a href="http://www.brimllc.com/2011/01/extending-selenium-2-0-webdriver-to-support-ajax/">previous article</a> and expose the API to be used. SeleniumUtility is just a helper class which reads a property file for values, so will leave it out.</p>
<pre>
  <code>
   import java.lang.reflect.Field;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
   import org.openqa.selenium.support.pagefactory.ElementLocator;

	public class AjaxListItemLocatorFactory extends AjaxElementLocatorFactory {

		private WebDriver driver;
		private int index;

        // SeleniumUtility is just a helper
		public AjaxListItemLocatorFactory(WebDriver driver, int index) {
			this(driver, index, SeleniumUtility.timeOutInSeconds);
		}

		public AjaxListItemLocatorFactory(WebDriver driver, int index, int timeOutInSeconds) {
			super(driver, timeOutInSeconds);
			this.driver = driver;
			this.index = index;
		}

		public ElementLocator createLocator(Field field) {
			return new AjaxListItemLocator(this.driver, field, this.index, SeleniumUtility.timeOutInSeconds);
		}

	}
  </code>
 </pre>
<p>  Now, how to use it. For example, I have a PageObject, which contains a link WebElement on click of which an element is added/removed. Here is how to use it.</p>
<pre>
    <code>
	 public class MyListItem implements
			IndexAwareItem {
		// Every item have an index
		int index = -1;
		// example for id or name
		@FindBy(how = How.ID_OR_NAME, using = "firstName#")
		RenderedWebElement firstNameElementTextBox;
		// example to use xpath
		@FindBy(how = How.XPATH, using = "//input[@type='text' and @name='lastName#'")
		RenderedWebElement lastNameElementTextBox;

		WebDriver driver;
		// necessary constructor to be used using PageFactory
		public MyListItem(WebDriver driver){
		  this.driver = driver;
		}

		// these methods are defined in IndexAwareItem interface
		public int getIndex() {
			return this.index;
		}

		public void setIndex(int index) {
			this.index = index;
		}

		public void populateItem(){
		  // do something here related to test
		}
	}

	public interface IndexAwareItem {
		public int getIndex();
		public void setIndex(int index);
	}
	</code>
  </pre>
<p>  So we defined the List Item, now use it in a page.</p>
<pre>
   <code>
     public class MyPageClass{
	  @FindBy(how = How.ID_OR_NAME, using = "addNewItem")
	  RenderedWebElement addNewItemLink;
	  WebDriver driver;

	  public MyPageClass(WebDriver driver){
		  this.driver = driver;
	  }

	  public void addNewItems(){
	    addNewItemLink.click();
		populateListItem(driver, 0);
		addNewItemLink.click();
		populateListItem(driver, 1);
	  }
	  public void populateListItem(WebDriver driver, int index){
	     MyListItem listItem = AjaxEnabledPageItemFactory
				.initElements(driver, MyListItem.class, index);
		// pass the index to MyListItem
		listItem.setIndex(index);
		listItem.populateItem();
		return listItem;
	  }
	 }
   </code>
  </pre>
<p>  So much to add index in the FindBy annotation, yep, thats what I thought as well. Its even more fun seeing it working.<br />
  Appreciate your comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.brimllc.com/2011/01/selenium-2-0-webdriver-extending-findby-annotation-to-support-dynamic-idxpath/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Extending Selenium 2.0 / WebDriver to support Ajax</title>
		<link>http://www.brimllc.com/2011/01/extending-selenium-2-0-webdriver-to-support-ajax/</link>
		<comments>http://www.brimllc.com/2011/01/extending-selenium-2-0-webdriver-to-support-ajax/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 17:24:09 +0000</pubDate>
		<dc:creator>Yagish Sharma</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.brimllc.com/?p=353</guid>
		<description><![CDATA[Recently I started using Selenium 2.0, which uses WebDriver to execute Automated test cases. It works great with normal static, page refreshing applications, but where Ajax is used extensively, this does not works reliably.
Selenium does comes with AjaxElementLocatorFactory, which creates instances of AjaxElementLocator. Now the idea is, if you send an Ajax request, this ElementLocator [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>Recently I started using Selenium 2.0, which uses WebDriver to execute Automated test cases. It works great with normal static, page refreshing applications, but where Ajax is used extensively, this does not works reliably.</p>
<p>Selenium does comes with AjaxElementLocatorFactory, which creates instances of AjaxElementLocator. Now the idea is, if you send an Ajax request, this ElementLocator waits for 250 milliseconds to look for the element, till it ultimately times out (configurable). The only exposed API from Selenium, that I found, was PageFactory, whose main purpose is to create a DefaultElementLocatorFactory, which does not wait. </p>
<p> So here are some of the modifications I had to make (using trial and error), to get this framework to work reliably (if you had similar luck, join the bandwagon <img src='http://www.brimllc.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). </p>
<p> First modification &#8211; Use what is provided. To expose AjaxElementLocatorFactory, I had to create a new extension of PageFactory class. Here it is -</p>
<pre>
  <code>
        package com.brim.selenium.locator;
        import java.lang.reflect.InvocationTargetException;
		import java.lang.reflect.Method;

		import org.apache.commons.lang.StringUtils;
		import org.openqa.selenium.WebDriver;
		import org.openqa.selenium.support.PageFactory;
		import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
		import org.openqa.selenium.support.pagefactory.ElementLocatorFactory;

		import com.brim.selenium.util.SeleniumUtility;

		public class AjaxEnabledPageFactory extends PageFactory {
		    // instantiatePageMethod is defined private in PageFactory, so use reflection to expose it,
			// or copy and paste. I hate copy/paste so implemented it using reflection

			static Method instantiatePageMethod = null;
			static {
				Method[] methods = PageFactory.class.getDeclaredMethods();
				for (Method method : methods) {
					if (StringUtils.equals(method.getName(), "instantiatePage")) {
						instantiatePageMethod = method;
						instantiatePageMethod.setAccessible(true);
					}
				}
			}

            // these are defined static in PageFactory, so had to copy this methods, to call my instantiatePage method
            // unfortunately, Java does not allow over-riding static methods, though compiler does not complain <img src='http://www.brimllc.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />
			public static  T initElements(WebDriver driver, Class pageClassToProxy) {
				T page = instantiatePage(driver, pageClassToProxy);
				initElements(driver, page);
				return page;
			}

			 // here is where i create AjaxElementLocatorFactory instance
			 // SeleniumUtility.timeOutInSeconds parameter is my own static parameter which is read from a property file
			 // more about it later
			public static void initElements(WebDriver driver, Object page) {
				final WebDriver driverRef = driver;
				initElements(new AjaxElementLocatorFactory(driverRef, SeleniumUtility.timeOutInSeconds), page);
			}

			 // another interesting issue i found, that sporadically Selenium/Webdriver throws
			 // StaleElementException, so it finds it, and while editing it throws that its stale,
			 // StaleReferenceAwareFieldDecorator does just that, if it sees the element is stale, look again.
			 // More about it later.
			public static void initElements(ElementLocatorFactory factory, Object page) {
				final ElementLocatorFactory factoryRef = factory;
				initElements(new StaleReferenceAwareFieldDecorator(factoryRef), page);
			}

			 // and here is the call to PageFactory's private instantiatePage method using my new AjaxEnabledPageFactory class.
			protected static  T instantiatePage(WebDriver driver,
					Class pageClassToProxy) {
				try {
					return (T) instantiatePageMethod.invoke(
							AjaxEnabledPageFactory.class, driver, pageClassToProxy);
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return null;
			}
		}

  </code>
 </pre>
<p>  So, now the first modification is done, how to use it- </p>
<pre>
    <code>
	  PageClass pageObject = AjaxEnabledPageFactory
				.initElements(driver, PageClass.class);
	</code>
  </pre>
<p>  Now, when I run my testcases, with configurable timeOut of 5 seconds, Selenium tries every 250 milliseconds to look the element, for max of 5 seconds and then throws ElementNotFoundException. Cool, everything should work now, I thought so too, then sporadically I will get StaleElementReferenceException. Now, PageFactory uses DefaultFieldDecorator, which decorates every WebElement / RenderedWebElement instance with a proxy. Any time, you execute a method on a WebElement, proxy forwards the request to the locator to locate the element first and then execute the method. But, sometimes, locator locates the webElement, but just before it tries to type in the textbox or click the button, the element is removed from DOM. So much for Ajax <img src='http://www.brimllc.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Simple solution, capture the StaleElementReferenceException, look again using locator and execute the method. Here is how to do it. </p>
<pre>
      <code>
	    import java.lang.reflect.InvocationHandler;
		import java.lang.reflect.InvocationTargetException;
		import java.lang.reflect.Method;
		import java.lang.reflect.Proxy;

		import org.apache.log4j.Logger;
		import org.openqa.selenium.RenderedWebElement;
		import org.openqa.selenium.StaleElementReferenceException;
		import org.openqa.selenium.WebElement;
		import org.openqa.selenium.internal.WrapsElement;
		import org.openqa.selenium.support.pagefactory.DefaultFieldDecorator;
		import org.openqa.selenium.support.pagefactory.ElementLocator;
		import org.openqa.selenium.support.pagefactory.ElementLocatorFactory;
		import org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler;

	    public class StaleReferenceAwareFieldDecorator extends DefaultFieldDecorator {
			private static final Logger logger = Logger
					.getLogger(StaleReferenceAwareFieldDecorator.class.getName());

			public StaleReferenceAwareFieldDecorator(ElementLocatorFactory factory) {
				super(factory);
			}

			protected WebElement proxyForLocator(ClassLoader loader,
					ElementLocator locator, boolean renderedProxy) {
				InvocationHandler handler = new StaleReferenceAwareElementLocator(
						locator);

				WebElement proxy;
				if (renderedProxy) {
					proxy = (RenderedWebElement) Proxy
							.newProxyInstance(loader, new Class[] {
									RenderedWebElement.class, WrapsElement.class },
									handler);
				} else {
					proxy = (WebElement) Proxy.newProxyInstance(loader, new Class[] {
							WebElement.class, WrapsElement.class }, handler);
				}
				return proxy;
			}

			private static class StaleReferenceAwareElementLocator extends
					LocatingElementHandler {
				private final ElementLocator locator;

				public StaleReferenceAwareElementLocator(ElementLocator locator) {
					super(locator);
					this.locator = locator;
				}

				// here is where the magic happens. For a configurable number of times (I configured
				// 5 times, locater finds the element, and then tries to invoke the method on the element
				// In case StaleElementReferenceException is thrown, try again.
				public Object invoke(Object object, Method method, Object[] objects)
						throws Throwable {
					int count = 0;
					WebElement element = null;
					while (count &lt; SeleniumUtility.numberOfTries) {
						try{
							element = locator.findElement();
						}catch(Exception ex){
							//logger.debug(&quot;Element not found&quot;, ex);
							SeleniumUtility.waitFor(250);
							count++;
							continue;
						}
						if (&quot;getWrappedElement&quot;.equals(method.getName())) {
							return element;
						}

						try {
							return invokeMethod(method, element, objects);
						} catch (StaleElementReferenceException ex) {
							//logger.debug(&quot;Error locating element&quot;, ex);
						}
						count++;
					}
					throw new RuntimeException(&quot;Cannot invoke &quot; + method.getName()
							+ &quot; on element &quot; + SeleniumUtility.getElementName(element)
							+ &quot;. Cannot find it&quot;);
				}

				private Object invokeMethod(Method method, WebElement element,
						Object[] objects) throws Throwable {
					logger.debug(&quot;Invoking &quot; + method.getName() + &quot; on &quot;
							+ SeleniumUtility.getElementName(element));
					try {
						return method.invoke(element, objects);
					} catch (InvocationTargetException e) {
						// Unwrap the underlying exception
						throw e.getCause();
					} catch (IllegalArgumentException e) {
						// Unwrap the underlying exception
						throw e.getCause();
					} catch (IllegalAccessException e) {
						// Unwrap the underlying exception
						throw e.getCause();
					}
				}
			}
		}
      </code>
   </pre>
<p>   Using these extensions, I atleast got rid of Ajax related issues. There were more modifications to extend the WebDriver&#8217;s FindBy annotations to include dynamic pages, where a link when clicked adds a new row in a table, and the id/name differs just by the index.<br />
   I will cover it in <a href="http://www.brimllc.com/2011/01/selenium-2-0-webdriver-extending-findby-annotation-to-support-dynamic-idxpath/">next article</a>. Btw, I used Selenium2.0a7 release.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.brimllc.com/2011/01/extending-selenium-2-0-webdriver-to-support-ajax/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Automating Performance Monitoring of a web application using AspectJ</title>
		<link>http://www.brimllc.com/2011/01/automating-performance-monitoring-of-a-web-application-using-aspectj/</link>
		<comments>http://www.brimllc.com/2011/01/automating-performance-monitoring-of-a-web-application-using-aspectj/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 17:19:50 +0000</pubDate>
		<dc:creator>Yagish Sharma</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.brimllc.com/?p=241</guid>
		<description><![CDATA[There are tons of Performance monitoring tools available, so why to get your hands dirty writing code to do something similar. Here is the issue, finding performance issues before you ship a release out the door is a dedicated effort. A performance engineer runs a load test, and then analyzes the reports to find if [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>There are tons of Performance monitoring tools available, so why to get your hands dirty writing code to do something similar. Here is the issue, finding performance issues before you ship a release out the door is a dedicated effort. A performance engineer runs a load test, and then analyzes the reports to find if the system is performing as per defined in SLA. If not, run the use case with the performance tool to find the bottleneck. It gets even worse, when the Performance tool itself adds a lot of overhead and slows the performance down. And overall procedure is deadly slow and time consuming. So, how can we automate the entire process, so we can gauge the performance of the application and compare with previous shipped releases, without going through this tedious process. Even better would be if we can find the component which is slowing down the entire application, down to the method level.</p>
<p>This is where AOP comes to rescue. I used AspectJ since the syntax is very similar to Java, and the learning curve is too small. The benefits, my original application code does not need any modification, just the JVM startup parameter to include aspectJWeaver.jar as my &#8220;-agent&#8221;, and my aspects jar in the classpath, and the magic happens using load time weaving. You can use other AOP frameworks.</p>
<p>Before I start, I assume that you have automated the use cases using Selenium or Canoe (or any other framework/tool), if not, its always a good idea so you can execute an Ant task to execute your entire test suite and also integrate it with the Continuous integration environment.</p>
<p>In a layered architecture, you have several components collaborating with each other. Ideally, they will have separate package names to identify which layer they belong to. Thats an implementation detail, but will help for reporting. I assume thats the case.</p>
<p>Lets start with the information we need to log for a usecase. Here is an execution record which I used based on my requirements.<br />
This blog suggests how we can use an AOP framework for performance monitoring and is highly customized to a specific project. I am sure there are better ways to implement the same solution, but this was easy enough to code and execute with little overhead.</p>
<pre><code>
package com.brimllc.aspects.record;
 /**
 * This record keeps the information in a ThreadLocal for each request. A parser
 * can later parse this information. The idea is if method A calls B, B calls C, and C calls D, then this will record
   the time it took only in that method. Like, A took 50 milli seconds in whole, and B took 30 millis, so the time spent in
   method A is just 20 millis.
 *
 */
public class ExecutionRecord {

	// client IP address, can be fetched from request header
	private String myClientIP;

	// request sequence, a single request processing can call multiple methods. Used for reporting
	private int myRequestSequenceNumber;

	// user who invoked the request, fetched from cookie or request session, for reporting
	private String myUserId;

	// session id to match the same, used for reporting
	private String mySessionId;

	// use case scenario, can be fetched from cookie, used for reporting
	private String myUseCaseScenario;

	// use case suite, selenium or canoe suite name
	private String mySuiteName;

	// execution path
	private String myExecutionPath;

	// request uri, used for reporting
	private String myRequestURI;

	// package name, identify the layer in which this method resides
	private String myPackageName;

	// method name
	private String myMethodName;

	// method execution count
	private int myMethodExecutionCount;

	// start time
	protected long myStartExecutionTime;

	// end time
	protected long myEndExcecutionTime;

	// total execution time
	protected long myTotalExecutionTime;

	// parent method
	private String myParentMethod;

	// has children flag
	private boolean myHasChildren = false;

	// total execution time of children
	private long myChildrenTotalExecutionTime;

	public ExecutionRecord() {

	}

	public ExecutionRecord(String userId, String sessionId, String useCase,
			String packageName, String method, int executionCount,
			long startTime, long endTime) {
		this.myUserId = userId;
		this.mySessionId = sessionId;
		this.myUseCaseScenario = useCase;
		this.myPackageName = packageName;
		this.myMethodName = method;
		this.myMethodExecutionCount = executionCount;
		this.myStartExecutionTime = startTime;
		this.myEndExcecutionTime = endTime;
	}

	public String getUserId() {
		return myUserId;
	}

	public void setUserId(String myUserId) {
		this.myUserId = myUserId;
	}

	// other getter and setters for the properties ...........

	public long getTotalExecutionTime(){
		this.myTotalExecutionTime = this.myEndExcecutionTime - this.myStartExecutionTime;
		return this.myTotalExecutionTime;
	}

	public long getExactExecutionTime() {
		return this.myEndExcecutionTime
		- this.myStartExecutionTime - this.myChildrenTotalExecutionTime;
	}

	// the method in whose scope this method is getting called.
	public String getParentMethod() {
		return myParentMethod;
	}

	public void setParentMethod(String myParentMethod) {
		this.myParentMethod = myParentMethod;
	}

	// overridden toString to dump to the log file.
	public String toString() {
		StringBuffer buff = new StringBuffer(100);
		buff.append(this.getClientIP()).append(
				PerformanceLogger.COLUMN_SEPARATOR);
		buff.append(this.getSequenceNumber())
		.append("."+Thread.currentThread().getId()).append(
				PerformanceLogger.COLUMN_SEPARATOR);
		buff.append(this.getUserId())
				.append(PerformanceLogger.COLUMN_SEPARATOR);
		buff.append(this.getSessionId()).append(
				PerformanceLogger.COLUMN_SEPARATOR);
		buff.append(this.getUseCaseScenario()).append(
				PerformanceLogger.COLUMN_SEPARATOR);
		buff.append(this.getSuiteName()).append(
				PerformanceLogger.COLUMN_SEPARATOR);
		buff.append(this.getExecutionPath()).append(
				PerformanceLogger.COLUMN_SEPARATOR);
		buff.append(this.getRequestURI()).append(
				PerformanceLogger.COLUMN_SEPARATOR);
		buff.append(this.getPackageName()).append(
				PerformanceLogger.COLUMN_SEPARATOR);
		buff.append(this.getMethodName()).append(PerformanceLogger.
		 COLUMN_SEPARATOR);
		// buff.append(this.getParentMethod()).append(PerformanceLogger.
		//		 COLUMN_SEPARATOR);
		buff.append(this.getStartExecutionTime()).append(PerformanceLogger.
				 COLUMN_SEPARATOR);
		buff.append(this.getEndExecutionTime()).append(PerformanceLogger.
				 COLUMN_SEPARATOR);
		// For debugging purposes only, enable this for each method's cumulative execution time
		// Also enable the Performance Logger to add another column in the file for Cumulative Execution time
		//buff.append(this.getTotalExecutionTime()()).append(PerformanceLogger.
		//		 COLUMN_SEPARATOR);
		buff.append(this.getExactExecutionTime());

		return buff.toString();
	}

	public boolean hasChildren() {
		return myHasChildren;
	}

	public void setHasChildren(boolean myHasChildren) {
		this.myHasChildren = myHasChildren;
	}

	public long getChildrenTotalExecutionTime() {
		return myChildrenTotalExecutionTime;
	}

	public void setChildrenTotalExecutionTime(long myChildrenTotalExecutionTime) {
		this.myChildrenTotalExecutionTime = myChildrenTotalExecutionTime;
	}

}

</code></pre>
<p> Now, lets put some basic bone structure, which handles the before and after execution of a method and populates this POJO. </p>
<pre><code>
  package com.brimllc.aspects;

  import java.util.Iterator;
  import java.util.Stack;
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  import javax.servlet.http.Cookie;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletRequestWrapper;
  import org.aspectj.lang.Signature;

  public abstract class AbstractLoggingAspect {
    // each HttpRequest is captured in this threadLocal to get access to request cookies and HttpSession
	protected static ThreadLocal myCurrentRequest = new ThreadLocal();
	protected static final String CURRENT_REQUEST_SEQUENCE_NUMBER = "CURRENT_REQUEST_SEQUENCE_NUMBER";
	protected static int MAX_REQUEST_NUMBER = 100000;
	// you dont want to monitor request for images, javascript etc, so lets ignore them
	protected static final Pattern PATTERN = Pattern.compile(".*/view/help/.*|.*/js/.*|.*/compressedJs/.*|.*/dynamicImage/.*|.*/images/.*|.*/css/.*|.*/a4j/.*");

	// here is the nuts and bolts, which does the calculation. Method A is the entry point, goes on the stack. A calls B,
	B goes on the stack over A, so the method just below is always the parent of the current method and so on. As each method ends execution, it pops from the stack.
	protected static ThreadLocal&lt;Stack&gt; myMethodCallStack = new ThreadLocal&lt;Stack&gt;(){
		protected synchronized Stack initialValue(){
			return new Stack();
		}
	};	

	/**
	 * Pointcut to exclude some packages. You dont want some methods defined which falls in the same packages, and will
	   match the pointcut, like EJB initilialization or MDB's onMessage which does not execute synchronously. You can get rid of it
       if you wish.
	 */
	public pointcut exclude():
		// do not include the aspects itself. Make sure the package of aspects is included,
		// else it will cause an infinite loop while weaving.
		!within(com.brimllc.aspects..*)
	   	// do not weave EJB container callbacks
		&amp;&amp; ! execution(* *.ejb*(..))
		&amp;&amp; ! execution(* *.setSessionContext(..))
		// do not weave JMS beans callbacks
		&amp;&amp; ! execution(* *.onMessage(..))
		&amp;&amp; ! cflowbelow(execution(* *.onMessage(..)))
		// do not weave any method which starts with WL
		&amp;&amp; ! execution(* *.__WL*(..))
		// do not include any exceptions
		&amp;&amp; ! within(java.lang.Exception+)
		&amp;&amp; !cflow(ping());

	/**
	 * This gets the information from the request
	 * @param parameter
	 * @return
	 */
	protected String getRequestInfo(HttpServletRequest request , String parameter){
		Cookie[] cookies = null;
		if(request.getRequestURI() == null || request.getRequestURI().length() == 0){
			logger.logDebug(" Request generated null pointer");
		}
		try{
			cookies = request.getCookies();
		}catch(Exception ex){
			cookies = null;

		}
		if(cookies == null || cookies.length == 0){
			return null;
		}

		String paramValue = null;
		for(Cookie c : cookies) {
	       if(c.getName().equals(parameter)) {
	    	   paramValue = c.getValue().replaceAll("%3A",":");
	    	   break;
	       }
	    }
		return paramValue;
	}

	/**
	 * Factory method to create ExecutionRecord
	 * @return
	 */
	protected ExecutionRecord createMethodExecutionRecord(){
		return new ExecutionRecord();
	}

	/**
	 * Updates the record with information from the request
	 * @param record
	 * @param signature
	 * @return
	 */
	protected ExecutionRecord updatedMethodExecutionRecord(HttpServletRequest request, ExecutionRecord record, Signature signature){
		if (request.getHeader("Proxy-Client-IP") == null){
			record.setClientIP(request.getRemoteAddr());
		} else {
			record.setClientIP(request.getHeader("Proxy-Client-IP"));
		}
		record.setRequestURI(request.getRequestURI());
		record.setSequenceNumber(getSequenceNumber(request));
		record.setUserId(getRequestInfo(request, "USERID"));
		record.setSessionId(getRequestInfo(request, "JSESSIONID"));
		record.setUseCaseScenario(getRequestInfo(request, "sfowTestCase"));
		record.setSuiteName(getRequestInfo(request, "testSuiteName"));
		record.setExecutionPath(getRequestInfo(request, "testSuiteCategory"));
		record.setPackageName(signature.getDeclaringType().getPackage().getName());
		record.setMethodName(signature.getDeclaringTypeName()+"."+signature.getName());
		record.setStartExecutionTime(System.currentTimeMillis());
		// check the top of the stack, thats the parent method which called this method
		ExecutionRecord parentRecord = myMethodCallStack.get().size() &gt; 0 ? myMethodCallStack.get().peek() : null;
		if(parentRecord != null){
			record.setParentMethod(parentRecord.getMethodName());
			parentRecord.setHasChildren(true);
		}
		return record;
	}

	/**
	 * Adds a record for method execution on the stack
	 * @param obj
	 */

	public void doBefore(Signature signature)
	{
		// no need to record till the request is sent to server
		HttpServletRequest request = myCurrentRequest.get();
		if(request == null){
			return;
		}
		// if the request is not a valid request then dont log
		if(!isValidRequest(request)){
			return;
		}
		// create a record
		ExecutionRecord record = createMethodExecutionRecord();
		// populate the record with information from request and method info
		updatedMethodExecutionRecord(request, record, signature);
		// push the record on top of the stack
		myMethodCallStack.get().push(record);
      }

	/**
	 * Pop the method record from the stack,
	 * add the end time of method
	 * calculate the total time executed for this method	 *
	 * @param obj
	 */
	public void doAfter(Signature signature)
	{
		// no need to record till the request is sent to server
		HttpServletRequest request = myCurrentRequest.get();
		if(request == null){
			return;
		}
		// if the request is not a valid request then dont log
		if(!isValidRequest(request)){
			return;
		}
		// pop the method from method call stack
		ExecutionRecord record =  myMethodCallStack.get().size() &gt; 0 ? myMethodCallStack.get().pop() : null;
		if(record == null){
			return;
		}
		// update the end time for method call
		record.setEndExecutionTime(System.currentTimeMillis());
		if(record.getTotalExecutionTime() &gt; 0){
			// now let the parents know I am done
			incrementParentsChildrenExecutionTime(record);
		}

		// log this record to the log file
		LogUtils.logTiming(record);
	}

	/**
	 * This method increments the childExecutionTime in the immediate parent record.
	 * Every method on the stack is still executing. Method on stack top is the current executing method (smallest child),
	 * while all others are its parents and waiting for it to finish to resume.
	 * When child method is finished executing, its execution time can be deducted from parent's execution time.
	 * * @param childRecord
	 */
	protected void incrementParentsChildrenExecutionTime(ExecutionRecord childMethodRecord){
		// increment the childExecutionTime of the immediate parent with childMethodRecord's total
		// execution time.
		ExecutionRecord parentRecord = myMethodCallStack.get().size() &gt; 0 ? myMethodCallStack.get().peek() : null;
		if(parentRecord == null){
			return;
		}
		parentRecord.setChildrenTotalExecutionTime(parentRecord.getChildrenTotalExecutionTime() + childMethodRecord.getTotalExecutionTime());
	}		

	 protected boolean isValidRequest(HttpServletRequest request){
		 if(request == null){
			 return false;
		 }

		 String requestURI = request.getRequestURI();
		 if(requestURI == null || requestURI.trim().length() == 0){
			 return false;
		 }

		// exclude any request for image, css or javascript
		 Matcher excludeMatcher = PATTERN.matcher(requestURI);
		 if(excludeMatcher.matches()){
			 return false;
		 }

		 return true;
	 }

	  // Other helper methods, no magic here
	 public synchronized int getSequenceNumber(HttpServletRequest request){
		 if(request.getSession(false) == null){
			 return 1;
		 }
		 Object currentReqSequenceObj = request.getSession(false).getAttribute(CURRENT_REQUEST_SEQUENCE_NUMBER);
		 if(currentReqSequenceObj == null){
			 return 1;
		 }
		 return ((Integer)currentReqSequenceObj).intValue();
	 }

	 public synchronized void incrementSequenceNumber(HttpServletRequest request){
		 if(request.getSession(false) == null){
			 return;
		 }
		 int currentReqSequence = getSequenceNumber(request);
		 if(currentReqSequence &lt; MAX_REQUEST_NUMBER){
			 currentReqSequence++;
		 }else{
			 currentReqSequence = 1;
		 }

		 request.getSession(false).setAttribute(CURRENT_REQUEST_SEQUENCE_NUMBER, new Integer(currentReqSequence));
	 }
}
 </code></pre>
<p> Now lets create the meat over the skeleton. Write some real aspects.<br />
 For every request sent to an Application server, there is always a base controller, or a filter which handle the request. In my case, I assume that there is a filter which gets the request first. Thats where we can get a handle to HttpRequest and check if it is not a valid request (ie. not image/css/javascript request).</p>
<pre><code>
    package com.brimllc.aspects;
	/**
 * This aspect captures the HttpRequest in a ThreadLocal variable.
 * The idea is to capture the request from the first filter the request hits.
 *
 */
public aspect CaptureRequest extends AbstractLoggingAspect {

	public pointcut entireExecutionOfOneRequest() :
		execution(public void com.brimllc.filter.FirstFilter.doFilter(..));

	 before() : entireExecutionOfOneRequest()
	    {

	      // capture the request from the doFilter method arguments
		  Object[] args = thisJoinPoint.getArgs();
	    	HttpServletRequest request = (HttpServletRequest)args[0];
			// check if the request is not an img/css/javascript request
	    	if(isValidRequest(request)){
		    	synchronized(this){
		    		HttpServletRequestWrapper reqWrapper = new HttpServletRequestWrapper(request);
					// set this request to the threadLocal defined in AbstractLoggingAspect
	    			myCurrentRequest.set(reqWrapper);
	    			incrementSequenceNumber(request);

		    	}
		    	// keep record, calls the AbstractLoggingAspect (the skeleton) passing the method signature
		    	doBefore(thisJoinPointStaticPart.getSignature());
	    	}

	    }	 

	    // since this is the entry point for the request, some more stuff is needed here, like clearing the Thread-Local,
		// the method stack used for calculation is reset.
	    after() : entireExecutionOfOneRequest()
	    {
	    	// process only when request is valid
	    	 // capture the request
		      Object[] args = thisJoinPoint.getArgs();
		      HttpServletRequest request = (HttpServletRequest)args[0];
		      if(isValidRequest(request)){
		    	doAfter(thisJoinPointStaticPart.getSignature());
		      }
		      // now get rid of request and any methods lying on the stack
		     myCurrentRequest.set(null);
		     myMethodCallStack.set(new Stack());
	     }

}
 </code></pre>
<p>  So, we hooked our framework to capture the entry point of the request to the filter, to capture the HttpRequest. Now lets capture one layer of the application. For example, we want to see how much time the request is taking in the data-access layer. Luckily, our package name for DAO layer is com.brimllc.dao (somebody thought ahead <img src='http://www.brimllc.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )</p>
<p>  And this is all thats needed -</p>
<pre><code>
   package com.brimllc.aspects;
   public aspect DAOAspect extends AbstractLoggingAspect {

	public pointcut daoCall():
		  // packages in Dao layer to weave
		 execution(public * com.brimllc.dao..*DaoImpl.*(..));		

	// exclude the calls to methods in the exclude list
	before() : daoCall() &amp;&amp; exclude(){
		doBefore(thisJoinPointStaticPart.getSignature());
	}

	after() : daoCall() &amp;&amp; exclude(){
		doAfter(thisJoinPointStaticPart.getSignature());
	}
}

  </code></pre>
<p>  For any other layer, just define a new aspect, with its own pointcut and call doBefore or doAfter defined in AbstractLoggingAspect in before or after advice. </p>
<p>  This was the coding part, now come to the execution part. For that you need to define an aop-ajc.xml for doing Load-Time weaving. AspectJ provides options of doing compile time or load time weaving. The difference is, the byte-code manipulation happens either when compiling the code, or AspectJ loads the class using its custom class-loader and then checks the aspects defined in aop-ajc.xml and injects the byte code if it matches the pointcut defined in the aspects. </p>
<pre><code>
     &lt;?xml version="1.0" encoding="UTF-8"?&gt;
    &lt;aspectj&gt;
     &lt;!-- configure the aspects we just created above --&gt;
		&lt;aspects&gt;
			&lt;aspect name="com.brimllc.aspects.CaptureRequest"/&gt;
			&lt;aspect name="com.brimllc.aspects.DAOAspect"/&gt;
		&lt;/aspects&gt;
		&lt;!-- configure the weaver --&gt;
		&lt;weaver options="-verbose -proceedOnError -Xset:fastWeaving=true,weaveJavaPackages=true,weaveJavaxPackages=true "&gt;
	     &lt;!--  -showWeaveInfo--&gt;
			&lt;include within="com.brimllc..*"/&gt;
			&lt;!-- incase you are using JSF libraries, yes you can define aspects and capture information on their methods as well --&gt;
			&lt;include within="com.sun.faces..*"/&gt;
			&lt;include within="javax.faces..*"/&gt;
			&lt;include within="org.ajax4jsf..*"/&gt;
			&lt;include within="com.sun.facelets..*"/&gt;

	&lt;!--  exclude list, packages that will not be weaved --&gt;

	&lt;!--  Other packages to exclude --&gt;
			&lt;exclude within="org.apache.commons.collections..*"/&gt;
			&lt;exclude within="org.apache.commons.logging..*"/&gt;
			&lt;exclude within="org.apache.naming..*"/&gt;
			&lt;exclude within="org.apache.log4j..*"/&gt;
			&lt;exclude within="org.apache.taglibs..*"/&gt;
			&lt;exclude within="org.apache.tools..*"/&gt;
			&lt;exclude within="org.apache.xerces..*"/&gt;
			&lt;exclude within="org.apache.xmlbeans..*"/&gt;
			&lt;exclude within="org.hibernate..*"/&gt;
			&lt;exclude within="net.sf.hibernate..*"/&gt;
			&lt;exclude within="weblogic.apache..*"/&gt;
			&lt;exclude within="weblogic.application..*"/&gt;
			&lt;exclude within="weblogic.deploy..*"/&gt;
			&lt;exclude within="weblogic.diagnostics..*"/&gt;
			&lt;exclude within="weblogic.ejb..*"/&gt;
			&lt;exclude within="weblogic.j2ee.descriptor..*"/&gt;
			&lt;exclude within="weblogic.jms..*"/&gt;
			&lt;exclude within="weblogic.management..*"/&gt;
			&lt;exclude within="weblogic.messaging..*"/&gt;
			&lt;exclude within="weblogic.rmi..*"/&gt;
			&lt;exclude within="weblogic.security..*"/&gt;
			&lt;exclude within="weblogic.store..*"/&gt;
			&lt;exclude within="weblogic.transaction..*"/&gt;
			&lt;exclude within="weblogic.utils..*"/&gt;
			&lt;exclude within="com.bea.common..*"/&gt;
			&lt;exclude within="com.bea.security..*"/&gt;
			&lt;exclude within="com.bea.staxb..*"/&gt;
			&lt;exclude within="com.bea.xbean..*"/&gt;
			&lt;exclude within="com.bea.xml..*"/&gt;
			&lt;exclude within="*..*CGLIB*" /&gt;
			&lt;exclude within='org.jboss..*'/&gt;
		&lt;/weaver&gt;
	&lt;/aspectj&gt;
</code></pre>
<p>   Now create a jar for this. I used Maven, so here is the POM.xml</p>
<pre><code>
		 &lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&gt;

		&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

		&lt;name&gt;Brim aspects&lt;/name&gt;
		&lt;description&gt;Aspects used to collect performance data &lt;/description&gt;

		&lt;parent&gt;
			&lt;groupId&gt;org.brimllc.perfAspects&lt;/groupId&gt;
			&lt;artifactId&gt;brim-perf-test&lt;/artifactId&gt;
			&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
		&lt;/parent&gt;

		&lt;artifactId&gt;perf-aspects&lt;/artifactId&gt;

		&lt;packaging&gt;jar&lt;/packaging&gt;

		&lt;dependencies&gt;
			&lt;dependency&gt;
				&lt;groupId&gt;javax.servlet&lt;/groupId&gt;
				&lt;artifactId&gt;servlet-api&lt;/artifactId&gt;
				&lt;scope&gt;provided&lt;/scope&gt;
			&lt;/dependency&gt;
			&lt;dependency&gt;
				&lt;groupId&gt;aspectj&lt;/groupId&gt;
				&lt;artifactId&gt;aspectj-tools&lt;/artifactId&gt;
			&lt;/dependency&gt;
			&lt;dependency&gt;
				&lt;groupId&gt;org.aspectj&lt;/groupId&gt;
				&lt;artifactId&gt;aspectjrt&lt;/artifactId&gt;
			&lt;/dependency&gt;
		&lt;/dependencies&gt;

		&lt;build&gt;
			&lt;plugins&gt;
				&lt;plugin&gt;
					&lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
					&lt;artifactId&gt;aspectj-maven-plugin&lt;/artifactId&gt;
					&lt;version&gt;1.2&lt;/version&gt;
					&lt;executions&gt;
						&lt;execution&gt;
							&lt;goals&gt;
								&lt;goal&gt;compile&lt;/goal&gt;
							&lt;/goals&gt;
						&lt;/execution&gt;
					&lt;/executions&gt;
					&lt;configuration&gt;
						&lt;complianceLevel&gt;1.6&lt;/complianceLevel&gt;
					&lt;/configuration&gt;
				&lt;/plugin&gt;
			&lt;/plugins&gt;
		&lt;/build&gt;

	&lt;/project&gt;
</code></pre>
<p> To execute this, just add the jvm arg -agent=aspectjweaver.jar and in classpath add the jar for aspects you created and run your usecases using Selenium/Canoe.</p>
<p> From the log file generated, you can create customized reports using JFreeChart or another framework.<br />
  Another use of this framework, if you are assigned to a new project with poor documentation and spaghetti design. Putting this framework in place you can capture the exact execution sequence of the class methods, and then refractor.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.brimllc.com/2011/01/automating-performance-monitoring-of-a-web-application-using-aspectj/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wicket Ajax Timer for Legthy Operations using AjaxSelfUpdatingTimerBehavior</title>
		<link>http://www.brimllc.com/2010/09/wicket-ajax-timer-for-legthy-operations-using-ajaxselfupdatingtimerbehavior/</link>
		<comments>http://www.brimllc.com/2010/09/wicket-ajax-timer-for-legthy-operations-using-ajaxselfupdatingtimerbehavior/#comments</comments>
		<pubDate>Mon, 27 Sep 2010 19:44:30 +0000</pubDate>
		<dc:creator>tmillhouse</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://www.brimllc.com/?p=248</guid>
		<description><![CDATA[Normally, if I have an operation that takes a while to complete in a wicket project, I&#8217;ve taken advantage of the LazyLoadingPanel. This works great for simple scenarios, but one major drawback for me is it doesn&#8217;t maintain its state across requests. Meaning, if a lazy loading operation is in process, and user decides to [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>Normally, if I have an operation that takes a while to complete in a wicket project, I&#8217;ve taken advantage of the LazyLoadingPanel. This works great for simple scenarios, but one major drawback for me is it doesn&#8217;t maintain its state across requests. Meaning, if a lazy loading operation is in process, and user decides to refresh the page or hit the back button, that process will be duplicated upon entering the page state again.</p>
<p>A colleague of mine discovered a better approach with the use of the Wicket AjaxSelfUpdatingTimerBehavior. When attached to a component, this behavior will cause the component to refresh continually (or until &#8220;stop()&#8221; is called), allowing the developer to implement lengthy operations within a new thread, which will be monitored by the onBeforeRender() method of the component. Lets take a look at how this is implemented:</p>
<p>For an example, lets say we have a process called ProcessOrder that invokes a few services which may cause it to be lengthy. We can create an &#8220;ajaxy&#8221; spinner to display while the ProcessOrder is executing, and then once the operation is complete, a session flag will be set, and the panel will update its view.</p>
<pre><code>
public class OrderPanel extends Panel{

     private WebMarkupContainer ajaxSpinner;
     private WebMarkupContainer orderConfirmation;
     private AjaxSelfUpdatingTimerBehavior updateBehavior;

     public OrderPanel(String id){
          super(id);

          add(ajaxSpinner = new WebMarkupContainer("ajaxSpinner"));
          add(orderConfirmation= new WebMarkupContainer("orderConfirmation"));
          orderConfirmation.setVisible(false);

          add(updateBehavior = new AjaxSelfUpdatingTimerBehavior(Duration
                .seconds(5));

          new OrderProcessThread(getSession()).start();
     }

     @Override
     protected void onBeforeRender() {
        super.onBeforeRender();

          if(((MySession)getSession()).isOrderProcessComplete(true)){
               // This means our worker thread has finished and updated the session.
               // Now, we can update our view states to show the order confirmation.
               ajaxSpinner.setVisible(false);
               orderConfirmation.setVisible(true);

               // don't forget to stop the update behavior
               updateBehavior.stop();
          }
     }

     private class OrderProcessThread extends Thread{

          private MySession session;

          public OrderProcessThread(Session session){
               this.session = (MySession) session;
          }

          @Override
          public void run() {
                try{
                // for the sake of this example, imagine this method will
                // invoke some service that will take a while to finish
                }catch(Exception e){
                }finally{
                     session.setIsOrderProcessComplete(true);
                }
          }
     }
}
</code></pre>
<p>The code above should be fairly straight forward, but I can expand on this if anyone would like more examples for further explanations. In a nutshell, the panel has two markup containers. One to show while our thread processes the order, and another to show some kind of confirmation message. Upon initialization, the spinner markup container is displayed and the confirmation markup container is set to be invisible. We then add the ajax updating behavior, which will cause a round trip &#8220;refresh&#8221; every 5 seconds (this is set within its initialization). The last thing we do is start our thread. </p>
<p>When the page is rendered, the ajax container will be displayed, and after 5 seconds, our Panel&#8217;s onBeforeRender() will again be invoked caused by the ajax request. Here, we can check if the thread has set the &#8220;IsOrderProcessComplete&#8221; flag, and if so, we can update our visual elements.</p>
<p>Keep in mind that the code above was written from memory for example purposes, and it is not intended to be production worthy. This is just the basic approach used to get the ajax timer implemented. As you can see, Wicket does a great job of making it easy for us developers to implement snazzy ajax applications with little code. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.brimllc.com/2010/09/wicket-ajax-timer-for-legthy-operations-using-ajaxselfupdatingtimerbehavior/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

