<?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>agimatec &#187; Javascript</title>
	<atom:link href="http://www.agimatec.de/blog/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.agimatec.de/blog</link>
	<description>Clash of realities</description>
	<lastBuildDate>Tue, 22 Dec 2009 16:50:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Influencing AJAX-GUIs With Metadata</title>
		<link>http://www.agimatec.de/blog/2009/04/influencing-ajax-guis-with-metadata/</link>
		<comments>http://www.agimatec.de/blog/2009/04/influencing-ajax-guis-with-metadata/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 16:13:43 +0000</pubDate>
		<dc:creator>roman.stumm</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Add new tag]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[Codegenerierung]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[metadata]]></category>
		<category><![CDATA[Portlet]]></category>
		<category><![CDATA[Validierung]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=606</guid>
		<description><![CDATA[This article explains how to create metadata that we use for scaffolding flexible AJAX GUIs . I keep the text as short as possible by providing a step-by-step cookbook based on code examples. What you should know: Metadata for scaffoling your GUI (described here). What you need to compile/run the examples: java1.5 or newer opensource [...]]]></description>
			<content:encoded><![CDATA[<p>This article explains how to create metadata that we use for scaffolding flexible AJAX GUIs . I keep the text as short as possible by providing a step-by-step cookbook based on code examples.</p>
<p>What you should know:</p>
<ul>
<li>Metadata for scaffoling your GUI (described <a title="Generate Your UI Using Metadata " href="http://www.agimatec.de/blog/2009/03/generate-your-ui-using-metadata/">here</a>).<span id="more-606"></span></li>
</ul>
<p>What you need to compile/run the examples:</p>
<ul>
<li>java1.5 or newer</li>
<li><a href="http://code.google.com/p/agimatec-validation/">opensource framework: agimatec-validation</a> : download agimatec-validation.jar</li>
<li>optional: javax.servlet.jar (servlet-api)</li>
<li>optional: <a href="http://code.google.com/p/agimatec-tools/">opensource frameworks/tools: agimatec-tools</a> : download annomark-dist.zip and annogen.jar</li>
</ul>
<p><strong>1. Create model classes</strong></p>
<p>We start with a plain java class, our model, used to transport attributes from the server to the GUI. (You can use <a title="Direct Web Remoting" href="http://directwebremoting.org/">DWR</a> for marshaling object instances between Java and JavaScript/JDOM).</p>
<p><strong>Example class &#8220;Business&#8221;:</strong></p>
<blockquote><p>import javax.persistence.*;</p></blockquote>
<blockquote><p>public class Business {<br />
@Id<br />
@Column(name=&#8221;business_id&#8221;, nullable=false, unique=true)<br />
Long businessId;<br />
@Column(name=&#8221;name&#8221;, nullable=false, unique=true, length=200)<br />
String name;<br />
@Column(name=&#8221;active&#8221;, nullable=false)<br />
boolean active;<br />
// getters, setters follow&#8230;<br />
}</p></blockquote>
<p><strong>2. Write or generate xml meta data</strong></p>
<p>You can write the xml meta data manually, or &#8211; if your classes have javax.persistence.* annotations &#8211; you can generate them using agimatec-tools/annomark.jar (described <a title="annomark explained" href="http://code.google.com/p/agimatec-tools/wiki/annomark">here</a>):</p>
<blockquote><p>&lt;bean id=&#8221;com.agimatec.Business&#8221; impl=&#8221;com.agimatec.Business&#8221;&gt;<br />
&lt;feature key=&#8221;mainKey&#8221;&gt;<br />
&lt;value class=&#8221;string&#8221;&gt;businessId&lt;/value&gt;<br />
&lt;/feature&gt;<br />
&lt;property name=&#8221;businessId&#8221;&gt;<br />
&lt;feature key=&#8221;uniqueKey&#8221;&gt;<br />
&lt;value class=&#8221;boolean&#8221;&gt;true&lt;/value&gt;<br />
&lt;/feature&gt;<br />
&lt;/property&gt;<br />
&lt;property name=&#8221;name&#8221; mandatory=&#8221;true&#8221; maxLength=&#8221;200&#8243;&gt;<br />
&lt;feature key=&#8221;uniqueKey&#8221;&gt;<br />
&lt;value class=&#8221;boolean&#8221;&gt;true&lt;/value&gt;<br />
&lt;/feature&gt;<br />
&lt;/property&gt;<br />
&lt;property name=&#8221;active&#8221; mandatory=&#8221;true&#8221;/&gt;<br />
&lt;/bean&gt;</p></blockquote>
<p>Store the file as &#8220;beaninfos-default.xml&#8221; in the classpath.</p>
<p><strong>2. Access the MetaBean</strong></p>
<p>This requires agimatec-validation.jar to compile:</p>
<blockquote><p>import com.agimatec.validation.MetaBeanManagerFactory;<br />
import com.agimatec.validation.model.MetaBean;</p>
<p>MetaBeanManagerFactory.getRegistry().<br />
addResourceLoader(&#8220;beaninfos-default.xml&#8221;);</p>
<p>MetaBean metabean = MetaBeanManagerFactory.getFinder().findForClass(Business.class);</p></blockquote>
<p><strong>3. Generate JSon for metabean(s)</strong></p>
<p>We want to use the meta data in the AJAX layer, to have information about the properties, their types and additional features (mandatory, max-length, &#8230;) as a JSON formatted string. agimatec-validation offers a JSONGenerator, based on a freemarker template:</p>
<blockquote><p>import com.agimatec.validation.json.JSONGenerator;</p>
<p>JSONGenerator generator = new JSONGenerator();<br />
String json = generator.toJSON(metabean);<br />
System.out.println(json);</p></blockquote>
<p>This prints this JSON string:</p>
<blockquote><p>agimatec.namespace(&#8220;agimatec.metadata&#8221;);</p>
<p>(function(){</p>
<p>var metaBean0 = {<br />
&#8220;id&#8221; : &#8220;com.agimatec.Business&#8221;,<br />
&#8220;beanClass&#8221; : &#8220;com.agimatec.Business&#8221;,<br />
&#8220;name&#8221; : &#8220;Business&#8221;,<br />
&#8220;features&#8221; :{   &#8220;mainKey&#8221; : &#8220;businessId&#8221;},<br />
&#8220;properties&#8221; :{<br />
&#8220;active&#8221;:{<br />
&#8220;name&#8221; : &#8220;active&#8221;,<br />
&#8220;type&#8221; : &#8220;boolean&#8221;,<br />
&#8220;features&#8221; : {       &#8220;mandatory&#8221; : true       }},<br />
&#8220;businessId&#8221;:{<br />
&#8220;name&#8221; : &#8220;businessId&#8221;,<br />
&#8220;type&#8221; : &#8220;long&#8221;,<br />
&#8220;features&#8221; : {       &#8220;uniqueKey&#8221; : true       }},<br />
&#8220;name&#8221;:{<br />
&#8220;name&#8221; : &#8220;name&#8221;,<br />
&#8220;type&#8221; : &#8220;java.lang.String&#8221;,<br />
&#8220;features&#8221; : {       &#8220;maxLen&#8221; : 200,       &#8220;mandatory&#8221; : true,       &#8220;uniqueKey&#8221; : true       }},<br />
&#8220;version&#8221;:{<br />
&#8220;name&#8221; : &#8220;version&#8221;,<br />
&#8220;type&#8221; : &#8220;int&#8221;,<br />
&#8220;features&#8221; : {       }}}};</p>
<p>agimatec.metadata.metaBeans = {&#8220;com.agimatec.Business&#8221; : metaBean0};})();</p></blockquote>
<p><strong>4. Write a servlet to deliver JSON for the AJAX GUI</strong></p>
<p>The java code for the servlet should not be a surprise, for it consists of what we have seen so far:</p>
<blockquote><p>public void init() throws ServletException {<br />
super.init();<br />
MetaBeanManagerFactory.getRegistry().addResourceLoader(&#8220;beaninfos-default.xml&#8221;);<br />
}</p>
<p>public void service(HttpServletRequest servletRequest, HttpServletResponse res)<br />
throws ServletException, IOException {<br />
Map&lt;String, MetaBean&gt; metaBeans = MetaBeanManagerFactory.getFinder().findAll();<br />
// output JSON:<br />
res.setContentType(&#8220;text/javascript&#8221;);<br />
PrintWriter writer = res.getWriter();<br />
String json = new JSONGenerator().toJSON(metaBeans.values());<br />
writer.write(json);<br />
}</p></blockquote>
<p>Thats basically all! With this infrastructure your AJAX GUIs have access to meta information about the model classes.</p>
<p><strong>5. Enrich meta data with information for the GUI-layer</strong></p>
<p>You can enrich the xml meta data with additional hints (field sequence, formats, &#8230;) &#8211; whatever your GUI needs. If hhe additional information cannot be generated automatically, you should keep them in a separate xml-file:</p>
<blockquote><p>&lt;bean id=&#8221;com.agimatec.Business&#8221;&gt;<br />
&lt;feature key=&#8221;DESCRIPTION&#8221;&gt;<br />
&lt;value class=&#8221;string&#8221;&gt;{name}&lt;/value&gt;<br />
&lt;/feature&gt;<br />
&lt;feature key=&#8221;SORTING&#8221;&gt;<br />
&lt;value class=&#8221;list&#8221;&gt;<br />
&lt;string&gt;name&lt;/string&gt;<br />
&lt;string&gt;active&lt;/string&gt;<br />
&lt;/value&gt;<br />
&lt;/feature&gt;<br />
&lt;!&#8211;Visualisation as table&#8211;&gt;<br />
&lt;feature key=&#8221;TABLE_COLUMNS&#8221;&gt;<br />
&lt;value class=&#8221;list&#8221;&gt;<br />
&lt;string&gt;name&lt;/string&gt;<br />
&lt;string&gt;active&lt;/string&gt;<br />
&lt;/value&gt;<br />
&lt;/feature&gt;<br />
&lt;/bean&gt;</p></blockquote>
<p>Save this as &#8220;beaninfos-gui.xml &#8221; in the classpath and register the file in the init() method of the servlet, too:</p>
<blockquote><p>MetaBeanManagerFactory.getRegistry().addResourceLoader(&#8220;beaninfos-gui.xml&#8221;);</p></blockquote>
<p>You see, that the JSON code will contain the additional information as well, because the MetaBeanManager merges them.</p>
<p>So far, we have the infrastructure to support meta data that allows us to build generic AJAX GUIs. The JSON string can be cached, because it will never change while the application is running.</p>
<p><strong>6. User-specific meta data</strong></p>
<p>We can go one step further: We can also support user-specific meta data! A usual requirement in a web application is, that &#8211; depending on the role of a user that is logged in &#8211; field-level permissions must be supported:<br />
User A is allowed to change the &#8220;active&#8221;-state of our &#8220;Business&#8221; entity, while User B has read-only access to the field and the field is hidden for User C, &#8230;</p>
<p>This could also be useful, when a user can customize its GUI (disable fields) by himself or when the application is used by different companies with different settings for their users&#8230;.</p>
<p>How does it work? &#8211; Use additional xml files and merge them in the JSON servlet. (You can also generate the meta beans during runtime programmatically).</p>
<p>beaninfos-role1.xml:</p>
<blockquote><p>&lt;bean id=&#8221;com.agimatec.Business&#8221;&gt;<br />
&lt;property name=&#8221;active&#8221;&gt;<br />
&lt;feature key=&#8221;readonly&#8221;&gt;<br />
&lt;value class=&#8221;boolean&#8221;&gt;true&lt;/value&gt;<br />
&lt;/feature&gt;<br />
&lt;/property&gt;<br />
&lt;/bean&gt;</p></blockquote>
<p>Extension of the servlet:</p>
<blockquote><p>String customInfos = &#8220;beaninfos-role1.xml&#8221;; // determine this from session or request dynamically!<br />
XMLMetaBeanInfos xmlInfos =<br />
new XMLMetaBeanURLLoader(getClass().getResource(customInfos)).load();<br />
Map&lt;String, MetaBean&gt; metaBeans =<br />
MetaBeanManagerFactory.getEnricher().enrichCopies(xmlInfos);</p></blockquote>
<p>The statements after &#8220;// output JSON&#8221; stay the same (see previous code fragment).</p>
<p><strong>More information?</strong></p>
<p>We already got some more posts in German about metadata and code generation, explaining the concepts and giving examples:</p>
<ul>
<li><strong></strong><strong><a title="TransferObjects generieren" href="http://www.agimatec.de/blog/2008/05/transferobjects-generieren/">TransferObjects generieren</a></strong></li>
<li><strong></strong><strong><a title="agimatec-tools als OpenSource auf google.code released!" href="http://www.agimatec.de/blog/2008/06/agimatec-tools-als-opensource-auf-googlecode-released/">agimatec-tools als OpenSource auf google.code released!</a></strong></li>
<li><strong></strong><strong><a title="Statt Modellieren: Annotieren und generieren" href="http://www.agimatec.de/blog/2008/04/statt-modellieren-annotieren-und-generieren/">Statt Modellieren: Annotieren und generieren</a></strong></li>
<li> <strong><a title="Klassen mit Mehrwert: Validierung und Metadaten" href="http://www.agimatec.de/blog/2008/04/klassen-mit-mehrwert-validierung-und-metadaten/">Klassen mit Mehrwert: Validierung und Metadaten</a></strong></li>
</ul>
<p>The open-source frameworks have a WIKI and additional examples or junit testcases, that help you.</p>
<p>If you have questions, do not hesitate to contact us!</p>
<p><span style="color: #333333;"><strong>This is the fifth article in our mini-series about developing highly ajaxified portlets. Other articles are:</strong></span></p>
<ul>
<li><strong><a href="http://www.agimatec.de/blog/2009/03/generate-your-ui-using-metadata/">Generate Your UI Using Metadata </a></strong></li>
<li><strong><a href="http://www.agimatec.de/blog/2009/02/client-side-inter-portlet-communication-done-right/">Inter Portlet Communication</a></strong></li>
<li><strong><a href="http://www.agimatec.de/blog/2009/01/using-yui-to-load-your-javascript-modules/">Using YUI loader for your own javascript modules</a></strong></li>
<li><strong><a href="http://www.agimatec.de/blog/2008/10/advanced_javascript_namespaces_for_portlets/">Portlet namespaces and javascript</a></strong></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2009/04/influencing-ajax-guis-with-metadata/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Generate Your UI Using Metadata</title>
		<link>http://www.agimatec.de/blog/2009/03/generate-your-ui-using-metadata/</link>
		<comments>http://www.agimatec.de/blog/2009/03/generate-your-ui-using-metadata/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 13:31:54 +0000</pubDate>
		<dc:creator>Sebastian Schuth</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[metadata]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=560</guid>
		<description><![CDATA[The team is small but tasks are legion. Business changes and you have to keep up. And you are doing ajax. You have to keep up. This is the situation we are in. And here is how we ease the pain: we are generating the user interface. Generating a Form To generate a form using [...]]]></description>
			<content:encoded><![CDATA[<p>The team is small but tasks are legion. Business changes and you have to keep up. And you are doing ajax. You have to keep up.</p>
<p>This is the situation we are in. And here is how we ease the pain: we are generating the user interface.</p>
<p><span id="more-560"></span></p>
<h1>Generating a Form</h1>
<p>To generate a form using our framework, you need to tell it :</p>
<ul>
<li>what should be edited</li>
<li>the type of what is edited</li>
</ul>
<p>Say we are building a form to edit a user object that contains user ip addresses:</p>
<pre name="code" class="javascript">
var user = {
	name:"Sebastian Schuth",
	ipAddress:"192.168.1.33",
	active:true
}
</pre>
<p>The form fields needed are described using object literals:</p>
<pre name="code" class="javascript">
var fields = [
	{
		key:'name', //name of the edited property
		label:'User name', //label to use in the form
		type: 'string',//type information
		permissioning:{denied: false, readonly: false}
	},
	{
		key:'active',
		label:'User is active',
		type: 'boolean',
		permissioning:{denied: false, readonly: false}
	},
	{
		key:'ipAddress',
		label:'IP Address',
		type: 'ipAddress',//this is a custom type
		permissioning:{denied: false,readonly: false}
	}
];
</pre>
<p>The properties needed for each field are:</p>
<ul>
<li><b>key</b> &#8211; name of the property that gets described by the entry</li>
<li><b>label</b> &#8211; description shown as label inside the form</li>
<li><b>type</b> &#8211; the type of the data stored in the property. This information is used by the framework to choose an editor implementation</li>
<li><b>permissioning</b> &#8211; data about what the user is allowed to do with the entry. This reflects what the server allows the user to do.</li>
</ul>
<p>Using this information, we can create a form using the following API:</p>
<pre name="code" class="javascript">
/**
 *

Adds a form with into the given container element using the given fieldDefinitions.

 *

The structure of the form's contents depend on the editor implementation inside fieldDefinitions. This
 * function creates just a form element as container for the elements the editors return and which it adds to the DOM.

 *

A Save button is added to the form as long as the <tt>addSaveBtn</tt>
 * config option is not set to <tt>false</tt>.
 * The <tt>fnOkCallback</tt> function must takes one parameter: it gets a new object filled with the values from the
 * created form.
 * 

 *
 * @param {object} namespace                The javascript portlet namespace (used to get I18N information)
 * @param {Element} container               HTML node to which the form is added
 * @param {object[]} fieldDefinitions       The definitions of the form fields
 * @param {function} fnOkCallback           Function which is called when the form's save button is clicked
 *                                          (if no save button is added (oConfig.addSaveBtn === false),
 *                                          this function is never called!)
 * @param {object} [oConfig]                Optional configuration.
 * @config {object} [formAttributes]        Attribute definitions for the form as key/value object.
 * @config {boolean} [addSaveBtn]           If <tt>false</tt>, no save button gets added to the form. Defaults to <tt>true</tt>.
 * @config {object[]} [additionalButtons]   Array of additional buttons that should get added left of the save button
 *                                          (if a save button is added) to the form.
 *                                          The contained objects need to members:
 *
<ul>
 *
<li><tt>label</tt> {string} Label of the button.</li>

 *
<li><tt>callback</tt> {function} Function called if the button gets clicked.</li>

 *                                          </ul>

 *                                          <b>Note:</b> Make sure to stop the click event inside the callback function
 *                                          to make sure that the form does not get send!
 *
 * @return {function} An error handling function that can be called to check for errors and add error messages to the
 * form as needed.
 */
agimatec.scaffolding.createForm = function(namespace, container, fieldDefinitions, fnOkCallback, oConfig){
	// ...
}
</pre>
<p>(as you can see, we are using JSdoc toolkit to generate our API docs)</p>
<p>So, let&#8217;s create a form:</p>
<pre name="code" class="javascript">
agimatec.scaffolding.createForm(this, formContainer, fields, null);
</pre>
<p>This call does two things: it creates a form inside <tt>formContainer</tt> and adds editor objects (read on to learn more about them!) to the field description objects given to it. </p>
<p>Now, we need to fill the form:</p>
<pre name="code" class="javascript">
agimatec.scaffolding.fillFields(user, fields);
</pre>
<p>Now, we can see what we have constructed:</p>
<div id="attachment_565" class="wp-caption alignleft" style="width: 573px"><img src="http://www.agimatec.de/blog/wp-content/uploads/2009/03/example-generated-form.png" alt="Form generated by the example code" title="From generated by the example code" width="563" height="171" class="size-full wp-image-565" /><p class="wp-caption-text">Form generated by the example code</p></div>
<p>Reading the values from the form is as easy as:</p>
<pre name="code" class="javascript">
var objectFromForm = {};
agimatec.scaffolding.readValues(objectFromForm, fields, callbackWhenDone);
</pre>
<p>After this call, <tt>objectFromForm</tt> contains all data as edited by the user.</p>
<h1>About Editors</h1>
<p>Inside the framework, editor objects are used to create the form parts needed to edit object properties. All an editor does is create a fieldset which is added to the form created by <tt>agimatec.scaffolding.createForm()</tt>, which itself gets added to the DOM.<br />
This means that if a special kind of data entry is needed, you will need to implement a special editor, which has to provide the following functions:</p>
<ul>
<li><tt>getReadWriteElement()</tt> &#8211; returns the DOM element used to edit entries</li>
<li><tt>getReadElement() - returns the DOM element used to display </tt></li>
<li><tt>setValue()</tt> &#8211; this is called by the framework when using <tt>agimatec.scaffolding.fillFields()</tt></li>
</ul>
<p>We have put together some editors (current count: 21), including ones to connect objects to other objects, upload files, entering IP addresses, weekdays, dates, times and so on. This makes maintaining our webapp much easier and guarantees the consistency our customers appreciate.</p>
<h1>Now entering the stage: Metadata</h1>
<p>Well, as easy defining fields using object literals is, this does not solve the issue of additions and changes to existing objects. This is where we added metadata to the mix. The metadata we get from the server tells us enough to create the field definitions we need to generate the forms! </p>
<p>So here we go:</p>
<pre name="code" class="javascript">
	/**
	 * Gets the field definitions for a dynamic form element (@see scaffolding.js).
	 * This function returns the sorted field definitions for a specified object. These describe which
	 * editor is used and adds further information like key and label to it.
	 * If we have an enum type, it adds also the options to an feature object.
	 * Features:
	 *
<ul>
	 *
<li>sorting of field definitions using a bean's SORTING feature</li>

	 *
<li>AJF type matching for root type and all related beans (depends if the feature "include" is set)</li>

	 *
<li>adding type of modelObject AJF type as feature "refBeanId"</li>

	 * </ul>

	 *
	 * @param {object} namespace    The javascript portlet namespace (used to get I18N information)
	 * @param {string} beanInfoId   The bean info id (e.g. 'com.agimatec.connecta.model.XFireTemplate')
	 *
	 * @return {object[]} Field definitions for the given beanInfoId.
	 */
	agimatec.metadata.getFieldDefinitions = function(namespace, beanInfoId) {/*...*/};
</pre>
<p>All you need to pass is which kind of object you want to display, the rest is handled by the framework.</p>
<h1>Whats next</h1>
<p>In this post, i explained how our framework makes creating forms for data entry easy and how we use metadata to make things even more &#8220;magic&#8221;. But this is not the end of the story. Our metadata is generated in a multi-step process, which will be described in a future post. To wet you appetite: we are generating metadata from multiple sources: Java Beans and XML descriptors and are able to merge multiple descriptors and user-based permissions.</p>
<p>Of course, generated UIs always need to be highly configurable to meet your user&#8217;s needs. Our framework offers a lot of options for this, up to defining rules that can manipulate the form reflecting what the user entered (and it looks like: <tt>formManager.when("lifecycleStatus").isSetTo("ACTIVE").changeForm(/*...actions...*/)</tt>). This makes the forms more friendly to use and prevents the user from doing things that make no sense. If you are interested, i would like to hear from you, just leave a comment.</p>
<p>Another theme i did not mention in the example is client-side validation. This is built in, too. And it is not hard to use, but explaining it would have made this article even longer. Again: if you are interested, leave a comment. If there is interest, i will blog about it. </p>
<p><span style="color: #333333;"><strong><br />
This is the fourth article in my mini-series about developing highly ajaxified portlets. In this blog, you can also find articles about:</p>
<ul>
<li><a href="http://www.agimatec.de/blog/2009/02/client-side-inter-portlet-communication-done-right/">Inter Portlet Communication</a></li>
<li><a href="http://www.agimatec.de/blog/2009/01/using-yui-to-load-your-javascript-modules/">Using YUI loader for your own javascript modules</a></li>
<li><a href="http://www.agimatec.de/blog/2008/10/advanced_javascript_namespaces_for_portlets/">Portlet namespaces and javascript</a></li>
</ul>
<p></strong></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2009/03/generate-your-ui-using-metadata/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Client-Side Inter Portlet Communication Done Right</title>
		<link>http://www.agimatec.de/blog/2009/02/client-side-inter-portlet-communication-done-right/</link>
		<comments>http://www.agimatec.de/blog/2009/02/client-side-inter-portlet-communication-done-right/#comments</comments>
		<pubDate>Tue, 10 Feb 2009 13:00:20 +0000</pubDate>
		<dc:creator>Sebastian Schuth</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Portlet]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=449</guid>
		<description><![CDATA[Using our framework, we are able to develop extremely modular portlet-based solutions that fit no matter how we combine them by using a service-publishing pattern.]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-525 alignright" title="gears" src="http://www.agimatec.de/blog/wp-content/uploads/2009/02/istock_000002874245xsmall.jpg" alt="gears" width="425" height="282" />Using portlets, you are able to develop tiny little applications that are suitable for a small subset of the actual functionality your customer wants. By combining them, they make it possible to create powerful but still modular applications that meet exactly the use cases your customer needs help with.</p>
<p>In theory.</p>
<p>In practice, you will be faced with a problem that is obviously a blind spot of the portlet definition (at least, the &#8220;old&#8221; JSR-186): how to communicate between portlets. The ability to mix-and-match portlets is key to a truly pluggable application formed of portlets.</p>
<p>To solve the communication problem, we have developed a solution much like the one <a href="http://www.liferay.com/web/jferrer/blog/-/blogs/1031319">developed by the folks at liferay</a>, but a bit more tuned and optimized for a fully pluggable solution.</p>
<p><span id="more-449"></span></p>
<h1>Portlet Services and Invokers</h1>
<p>Our implementation follows a simple pattern: Portlets are able to promote services to a page-central instance and can include interaction elements that are used to invoke services that match certain criteria:</p>
<ul>
<li>the type of object the service must be able to handle</li>
<li>the type of operation the service offers</li>
</ul>
<p>Promoting a service to other portlets includes:</p>
<ul>
<li>specifying what type of operation (CREATE/READ/UPDATE/DELETE) is offered</li>
<li>a text telling the user what happens when invoking the service</li>
<li>the function that should get called on service activation</li>
</ul>
<p>Using these simple building blocks we can offer users a list of actions that are available for a specific object:</p>
<h1>Completely discoupled</h1>
<p>The major advantage of our solution is that we do not hard-wire which portlets offers what to other portlets. All you have to do is insert a service invoker into the UI and the framework does the work for you. All people working on the project can work in parallel, the communication overhead is minimal. All the developers must do is offering a portlets services using the framework and give services a name that speaks.</p>
<p>This makes turns our product into a completely customizable platform that fits exactly our users&#8217;s needs.</p>
<h1>Maximum flexibility</h1>
<p>The framework makes splitting up responsibilities between portlets easy and puzzling just the right application for the job together possible. After adding a new portlet to a page, all service menus are automatically updated to offer new services that may have been added by the new portlet.</p>
<div id="attachment_451" class="wp-caption alignnone" style="width: 313px"><img class="size-full wp-image-451 " title="Service menu showing some services that may be invoked" src="http://www.agimatec.de/blog/wp-content/uploads/2009/01/service-menu2.jpg" alt="Service menu" width="303" height="223" /><p class="wp-caption-text">A generated service menu</p></div>
<div id="attachment_452" class="wp-caption alignnone" style="width: 415px"><img class="size-full wp-image-452 " title="Service menu for another set of portlets, showing additional &quot;Ping&quot; service" src="http://www.agimatec.de/blog/wp-content/uploads/2009/01/service-menu.jpg" alt="Service menu for a different set of portlets" width="405" height="172" /><p class="wp-caption-text">Service menu for a different set of portlets</p></div>
<p>What you see in these screenshots is that depending on which portlets are available, the portlet will offer different actions for an object (for Screenshot 2, the &#8220;Ping&#8221; portlet was added). All information about which services are available is calculated client-side and for the current setup. Adding a new portlet will add its services to the actions list. The text that appears inside the menu is set by the portlet offering the service.</p>
<p><img class="size-full wp-image-534 alignnone" title="Service menu and service button" src="http://www.agimatec.de/blog/wp-content/uploads/2009/02/servicemenuandbutton.png" alt="Service menu and service button" width="629" height="147" /></p>
<p>Invoking services is not limited to the context menus. We also use buttons for services that enable the creation of new items.</p>
<h1>Impacts on portlet design</h1>
<p>All this makes it easy to develop portlets that are designed to fulfill small tasks the right way. Reusability of portlets is massively increased. And on top of all this you get a consistent usage pattern that your customers will be familiar with when you are adding more functionality.</p>
<p><span style="color: #333333;"><br />
</span></p>
<p><span style="color: #333333;"><strong>This is the third article in my mini-series about developing highly ajaxified portlets. In this blog, you can also find articles about:</strong></span></p>
<ul>
<li><span style="color: #333333;"><strong><a href="http://www.agimatec.de/blog/2009/01/using-yui-to-load-your-javascript-modules/">Using YUI loader for your own javascript modules</a><br />
</strong></span></li>
<li><span style="color: #333333;"><strong><a href="http://www.agimatec.de/blog/2008/10/advanced_javascript_namespaces_for_portlets/">Portlet namespaces and javascript</a></strong></span></li>
</ul>
<p><span style="color: #333333;"><strong>In my next post in this series, i will give a little insight into how we use metadata generated by our server to make creating a fully ajax portlet a breeze. Meanwhile, check out our posts about testing our Ajax frontends using <a href="http://www.agimatec.de/blog/2008/08/selenium-testing-of-massive-ajax-apps/">Selenium</a> and the <a href="http://www.agimatec.de/blog/2009/01/javascript-unit-tests-with-the-yui-testmanager/">YUI Test framework</a>.</strong></span><em><br />
</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2009/02/client-side-inter-portlet-communication-done-right/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Javascript Unit Tests with the YUI TestManager</title>
		<link>http://www.agimatec.de/blog/2009/01/javascript-unit-tests-with-the-yui-testmanager/</link>
		<comments>http://www.agimatec.de/blog/2009/01/javascript-unit-tests-with-the-yui-testmanager/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 14:02:30 +0000</pubDate>
		<dc:creator>Simon Tiffert</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[Test]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=473</guid>
		<description><![CDATA[Testing your Javascript is very important. Especially when the amount of code is growing and growing. The easiest method are unit tests. We have tried several JS unit test frameworks. Including JSUnit, Scriptaculous Unit Test Runner and YUI test. With a lot of YUI components like the YUI Loader and many YUI widgets we refactored [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-474" href="http://www.agimatec.de/blog/2009/01/javascript-unit-tests-with-the-yui-testmanager/steps-2/"><img class="alignleft size-full wp-image-474" title="steps" src="http://www.agimatec.de/blog/wp-content/uploads/2009/01/steps.jpg" alt="steps" width="425" height="282" /></a>Testing your Javascript is very important. Especially when the amount of code is growing and growing.</p>
<p>The easiest method are unit tests. We have tried several JS unit test frameworks. Including JSUnit, Scriptaculous Unit Test Runner and YUI test. With a lot of YUI components like the <a href="http://www.agimatec.de/blog/2009/01/using-yui-to-load-your-javascript-modules/">YUI Loader</a> and many <a href="http://developer.yahoo.com/yui/">YUI widgets</a> we refactored our unit tests to use YUI Test. We like the Yahoo User Interface because of its documentation and also of its code quality.</p>
<p>YUI Test is not bundled with YUI. You can use it with YUI but we also use other frameworks like Prototype and DWR. To learn more about YUI Test you can <a href="http://developer.yahoo.com/yui/yuitest/">watch the presentation of Nicholas C. Zakas</a>.</p>
<p>Ok, this is great, now I can test my Javascript. But wait, what is if I have a lot of Javascript. I can group my tests in test cases and test cases in test suites. This is supported. But while the amount of Javascript is growing one file for all tests isn&#8217;t enough. We have a lot of different modules. Each consists of a lot of test cases. Sure, you can copy them all together in a file which is several thousand lines long. But every test run takes then a lot of time, debugging is more complex and it is more complicated to manage this file.</p>
<p><span id="more-473"></span></p>
<h2>YUI TestManager</h2>
<p>Wouldn&#8217;t it be great to have a test runner. A script which takes a lot of unit test files and run them one after another.  Our first approach was based on the Scriptaculous Unit Test Runner embedded in a frameset. We had a navigation frame and some Javascript included to run one unit test file in the main frame. One problem was to collect the results of all unit test files. We patched the Unit Test Runner and collected the data. It was ok and I wanted to refactor the solution to publish it. After starting I suddenly found an undocumented feature of YUI Test &#8211; The <a href="http://developer.yahoo.com/yui/docs/YAHOO.tool.TestManager.html">YUI TestManager</a>. It is exactly what I wanted to do, define the unit test files, run through all of them and collect the results. I think Yahoo is using this feature internally and didn&#8217;t talk a lot about it. But it is included in the <a href="http://developer.yahoo.com/yui/docs/YAHOO.tool.TestManager.html">API</a>, so please YUI team, include it to the documentation. It is a great piece of code.</p>
<h2>Continuous Integration of Javascript with Selenium</h2>
<p>Before I will show you how to use it, some more thoughts about this. We are coming from the agile Java world. So continuous integration is very important for us. Please search for &#8220;Continuous Integration Javascript&#8221; in your search machine. There are just a few hits and no ready to use solution. Yes, you can try to go back to the Java world and run tests with Rhino. There are some Java based unit test frameworks for Javascript. But there are two downsides. You are leaving the Javascript world and you are leaving the browser. It can be ok for you but I don&#8217;t trust the different browsers. I want to be able to run the tests fast in the browser when I&#8217;m developing and I want to test as many browsers as I can. We searched for a solution and what we have running is a suite of Selenium tests. They are at another level. Functional tests which run through use cases in the web frontend. But if we could give them a result of our unit tests we are able to include this in our setup. Then we can run the unit tests in IE, Firefox and Opera automatically.</p>
<p>YUI Test gives you the logger to view the results of your tests. It is not the best view for test results but it is ok. Also there are a lot of events which include the results of the tests after running them. We have implemented a little script which displays a nice summary which we test with Selenium.</p>
<h2>Source code</h2>
<p>Now let&#8217;s head to the source code.</p>
<p>At the beginning we need a unit test. Because I&#8217;m want to concentrate on the TestManager you will find a very very simple test.</p>
<pre name="code" class="javascript">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
&lt;head&gt;
    &lt;title&gt;String test&lt;/title&gt;

    &lt;!--CSS--&gt;
	&lt;link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.6.0/build/logger/assets/logger.css"&gt;
	&lt;link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.6.0/build/yuitest/assets/testlogger.css"&gt;

	&lt;!-- Dependencies --&gt;
	&lt;script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/yahoo-dom-event/yahoo-dom-event.js"&gt;&lt;/script&gt;
	&lt;script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/logger/logger-min.js"&gt;&lt;/script&gt;

	&lt;!-- Source File --&gt;
	&lt;script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/yuitest/yuitest-min.js"&gt;&lt;/script&gt;

    &lt;script type="text/javascript"&gt;
    YAHOO.tool.TestRunner.add(new YAHOO.tool.TestCase({

        name: "String test",

        testEqualityAsserts : function () {
            var Assert = YAHOO.util.Assert;

            Assert.areEqual("hel"+"lo", "hello");     //passes
            Assert.areEqual("YUI test".substr(0,3), "YUI");     //passes
        }
    }));

    YAHOO.util.Event.onDOMReady(function (){

	    if (parent &#038;&#038; parent.TestManager) {
            parent.TestManager.load();
        }
        else {
            var logger = new YAHOO.tool.TestLogger();

            //run the tests
            YAHOO.tool.TestRunner.run();
        }
  	});
  	&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>In the first part we define our tests. In the second part you will see that the test will be called after the DOM is ready. It is a little bit different from the normal examples, because we call <em>parent.TestManager.load()</em> if it is available. Now you can copy this code, write your own tests, define test suites, &#8230; It starts to get interesting, if you have so many tests, that you want to group them into different files. With the code above you can go ahead and  create multiple tests. In the example code I have created to test files calcTest.html and stringTest.html.</p>
<p>To run all tests in all your test files you need to call the TestManager:</p>
<pre name="code" class="html">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
&lt;head&gt;
    &lt;title&gt;JS Unit Tests&lt;/title&gt;
    &lt;meta http-equiv="content-type" content="text/html; charset=utf-8"/&gt;

    &lt;!--CSS--&gt;
    &lt;link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.6.0/build/logger/assets/logger.css"&gt;
    &lt;link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.6.0/build/yuitest/assets/testlogger.css"&gt;

    &lt;!-- Dependencies --&gt;
    &lt;script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/yahoo-dom-event/yahoo-dom-event.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/logger/logger-min.js"&gt;&lt;/script&gt;

    &lt;!-- Source File --&gt;
    &lt;script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/yuitest/yuitest-min.js"&gt;&lt;/script&gt;

    &lt;!-- Source file --&gt;
    &lt;script type="text/javascript"&gt;
    	var TestManager = YAHOO.tool.TestManager;

        TestManager.setPages([
            "./stringTest.html",
            "./calcTest.html"
            ]);

        YAHOO.util.Event.onDOMReady(function() {
        	TestManager.start();
        });
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;h1&gt;JS Unit Tests&lt;/h1&gt;

&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>That&#8217;s simple, isn&#8217;t it?</p>
<p>That will give you the following output:<br />
<img src="http://www.agimatec.de/blog/wp-content/uploads/2009/01/logger.png" alt="logger" title="logger" width="656" height="303" class="alignnone size-full wp-image-491" /></p>
<p>We wanted to give it more the feeling of a unit test suite. As I told you there is an event after test completion, which includes the test results. With our script we are building a summary table which gives you a nice overview for your test results.<br />
<img src="http://www.agimatec.de/blog/wp-content/uploads/2009/01/testrunner.png" alt="testrunner" title="testrunner" width="713" height="502" class="alignnone size-full wp-image-492" /></p>
<p>With the overview table we also can track the results with a simple Selenium test:</p>
<pre name="code" class="java">
package com.agimatec.ostium.portlets.jsunit;

import com.agimatec.ostium.portlets.util.ScreenshottingSelenium;
import com.thoughtworks.selenium.Selenium;
import org.testng.Assert;
import org.testng.Reporter;
import org.testng.annotations.*;

public class JsUnitTest {
    Selenium selenium;

    @BeforeMethod
    @Parameters({"selenium.host", "selenium.port", "browser", "baseUrl", "ostium.login",
            "ostium.password"})
    public void startSelenium(
            @Optional("localhost")String host,
            @Optional("4444")int port,
            @Optional("*firefox")String browser,
            @Optional("http://localhost:8080")String baseUrl
    ) throws Exception {
        Reporter.log("Running selenium");
        selenium = new ScreenshottingSelenium(host, port, browser, baseUrl);
        selenium.start();
    }

    @Test
    public void checkPassedJsUnitTests() throws InterruptedException {
        selenium.open("/portlets/ostium/utilities/ajf/src/test/javascript/testrunner.html");
        for (int second = 0; ; second++) {
            if (second >= 60) Assert.fail("timeout");
            try {
                if (selenium.isElementPresent("//div[@id='testcontainer']/div/h2")) break;
            } catch (Exception e) {
            }
            Thread.sleep(1000);
        }

        Assert.assertTrue(
                selenium.isTextPresent("exact:Result: Passed"),
                "The result of the JS tests should be 'PASSED'.");
    }

    @AfterMethod
    public void stopSelenium() {
        Reporter.log("Stopping selenium");
        selenium.stop();
    }
}
</pre>
<p>The only thing to do is to run the files on a local server. We use a Jetty with Maven to host the files because Selenium needs to include a proxy which didn&#8217;t work if you access the file directly. </p>
<p>Find more to Selenium on our other posts:</p>
<ul>
<li><a href="http://www.agimatec.de/blog/2008/08/selenium-testing-of-massive-ajax-apps/">Selenium testing of massive Ajax Apps</a></li>
<li><a href="http://www.agimatec.de/blog/2008/07/selenium-ci-tests-with-teamcity/">Selenium CI tests with TeamCity</a></li>
<li><a href="http://www.agimatec.de/blog/2008/07/robust-portlet-testing/">Robust portlet testing</a></li>
</ul>
<p><a href='http://www.agimatec.de/blog/wp-content/uploads/2009/01/yuitestmanager.zip'>Download the script and some examples here.</a> We are planning to release it with some other JS stuff as a Google code project, but we are still searching for a name. </p>
<p>If this post was helpful or you have additional ideas, please don&#8217;t hesitate to comment. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2009/01/javascript-unit-tests-with-the-yui-testmanager/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Using YUI to load your Javascript modules</title>
		<link>http://www.agimatec.de/blog/2009/01/using-yui-to-load-your-javascript-modules/</link>
		<comments>http://www.agimatec.de/blog/2009/01/using-yui-to-load-your-javascript-modules/#comments</comments>
		<pubDate>Mon, 19 Jan 2009 14:25:53 +0000</pubDate>
		<dc:creator>Sebastian Schuth</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Portlet]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=398</guid>
		<description><![CDATA[As promised earlier, i&#8217;ll discuss in this post how we load the Javascript modules we have written over the last months. Please note that despite i am mainly talking about portlets in this post, the technique described is also usable in web applications that need to load additional Javascript after page load. The setting Let [...]]]></description>
			<content:encoded><![CDATA[<p>As <a href="http://www.agimatec.de/blog/2008/10/advanced_javascript_namespaces_for_portlets/">promised earlier</a>, i&#8217;ll discuss in this post how we load the Javascript modules we have written over the last months. Please note that despite i am mainly talking about portlets in this post, the technique described is also usable in web applications that need to load additional Javascript after page load.</p>
<h1>The setting</h1>
<p>Let me explain the structure of our project a bit. The main constraint we are facing when developing rich user interfaces for the web platform is that we were up to do so using Java Portlets. Using the portlets standard (JSR-168), we are able to meet our customer&#8217;s needs in a way we never could have done when developing traditional, monolithic web applications. But this flexibility comes at a price: we do not know which apps are on a page when it gets loaded; further, we want to be able to add new portlets to each page at any time. From a Javascript perspective, this means that traditional &#8220;just put script tags into the header&#8221;-style Javascript coding will lead to a very bad user experience, since every page would be bloated with stuff the user will never use and &#8211; even more important- the user experience will degrade as we are adding new features to our product, even if our customer does not need or want the new features. As explained before, adding Javascript code to HTML/JSP Parts of the Portlets were no option and would have caused massive double-loading of script code. As our platform grew, we saw the need to put together a Javascript library to support code reuse up front. We clearly needed a mechanism to load our Javascript modules as they are needed. After some experiments (including the use of unholy synchronous XHR calls&#8230; shame on me!), we tried the YUI Loader.</p>
<h1>Meet the YUI Loader Utility</h1>
<p>Its no secret that we are using YUI in our product. As YUI comes with a special module for loading dependencies, the YUI Loader Utility, we explored if we could use YUI for our needs. The Loader&#8217;s <a href="http://developer.yahoo.com/yui/yuiloader/">feature list</a> reads like our wish-list:</p>
<ul>
<li>Reliable, sorted loading of dependencies</li>
<li>Safe, efficient mechanism for adding new components to a page on which YUI may already be present.</li>
<li>Automatic use of rolled-up files.</li>
</ul>
<p>So we&#8217;ve developed our own solution on top of the YUI loader for our Framework. It consists of two components: A Compile-time dependency analyzer and a configuration file generated by the dependency analyzer that tells YUI how to load our modules.</p>
<h1>Analyzing JS dependencies</h1>
<p>First of all, every JS module file starts with a set of comments telling the dependency analyzer how the current module is called and what modules are required by the declared module:</p>
<pre class="js">// @@module agimatec.topic
// @@requires event, agimatec.datatypes

// Module code goes here
// ...
// ...
// ...
// ...
// ...

// Tell the loader that this module has been loaded
YAHOO.register("agimatec.topic", agimatec.topic, {version:'1.0',build:'000'});</pre>
<p>The analyzer (which is current implemented as stand-alone groovy script that is run by maven &#8211; we have plans to implement it as maven Mojo) parses the dependency information in the module files and generates a Javascript configuration file for the YUI loader from it:</p>
<pre class="js">// ******************************
// Generated Code - DO NOT EDIT
// ******************************
/*
  This script adds all AJF module definitions to the YUI Loader utility as noted by
  '// @@' - style comments inside the *.js files.
  If the global variable 'agimatec_config' is not defined, it is defined by this script.
*/
(function(){
    var arrModules =[

            //...

            {
             name:'agimatec.scaffolding',
             type:'js',
             skinnable:false,
             path: '../../agimatec/scaffolding-2.1.11-SNAPSHOT-min.js',
             requires:["yahoo","event","calendar","tabview","agimatec.topic","agimatec.util","agimatec.util.table","agimatec.util.element","agimatec.util.minibrowser","agimatec.util.datePicker","agimatec.util.hintedText","agimatec.validator","agimatec.metadata"]},

            {
             name:'agimatec.topic',
             type:'js',
             skinnable:false,
             path: '../../agimatec/topic-2.1.11-SNAPSHOT-min.js',
             requires:["event","agimatec.datatypes"]},

            {
             name:'agimatec.util.browser',
             type:'js',
             skinnable:false,
             path: '../../agimatec/util/browser-2.1.11-SNAPSHOT-min.js',
             requires:["yahoo","dom","event","animation","datatable","agimatec.topic","agimatec.util","agimatec.util.yui","agimatec.util.lucene","agimatec.util.element","agimatec.preferences"]},

            {
             name:'agimatec.util.connector',
             type:'js',
             skinnable:false,
             path: '../../agimatec/util/connector-2.1.11-SNAPSHOT-min.js',
             requires:["yahoo","dom","event","container","datatable","agimatec.util","agimatec.metadata","agimatec.util.table","agimatec.portletservice","agimatec.util.minibrowser"]},

            {
             name:'agimatec.util.context',
             type:'js',
             skinnable:false,
             path: '../../agimatec/util/context-2.1.11-SNAPSHOT-min.js',
             requires:["agimatec.metadata","agimatec.util"]},

            {
             name:'agimatec.util.datePicker',
             type:'js',
             skinnable:false,
             path: '../../agimatec/util/datePicker-2.1.11-SNAPSHOT-min.js',
             requires:["yahoo","dom","event","agimatec.util","agimatec.util.hintedText"]},

		 // ...
    ];

    agimatec_config = agimatec_config || {};
    agimatec_config._modules = arrModules;
    agimatec_config.getLoader = function(){
        var modulesLength=agimatec_config._modules.length, i;
        var configObject = {};
        configObject.base = agimatec_config.yuiBasePath;
        if(agimatec_config.moduleFilter){
            configObject.filter=agimatec_config.moduleFilter;
        }
        if(undefined !== agimatec_config.allowRollup){
            configObject.allowRollup = agimatec_config.allowRollup;
        }
        // configure the default skin
        configObject.skin = {
            'defaultSkin':agimatec_config.defaultSkinName,
            'base': 'assets/skins/',
            'path': 'skin.css',
            'rollup': 3
        };
        var loader = new YAHOO.util.YUILoader(configObject);
        for(i=0; i</pre>
<p>This file is included inside the header of every portlet page. You see that thanks to the YUI Loader, we can mix YUI modules with our own ones without hassle, making development of a comprehensive Javascript Library much easier. (If your wondering why we add version numbers to the referenced module names, <a href="http://www.agimatec.de/blog/2008/07/cache-refresh/">see this article</a>)</p>
<p>Loading a module is as easy as:</p>
<pre class="js">// ...

var loader = agimatec_config.getLoader()
loader.require("agimatec.topic");
loader.insert(function(){
	// use agimatec.topic and ALL of its dependencies here !!!!
});</pre>
<p>You see that using modules is very easy. All you have to do is to tell the loader what you need and provide a function that should get executed as soon as the dependencies are resolved by adding the noted Javascript files.<br />
This solution served us very well in the last months, in fact our complete webapp development depends on this loading mechanism. It made growing a stable and feature-rich javascript library possible for us without destroying the user experience.</p>
<p>This post just scratches the features of our Javascript module tooling. We have also added support for a module description file format that allows us to describe Javascript modules using XML and generate the loading and dependency management code, along with support for &#8220;rollup&#8221; JS modules that allow us to reduce the number of requests needed to load portal pages.</p>
<p>If you are interested in this component, just tell us so in the comments and we will see how fast we can get this utility out of the door as Open Source.</p>
<p>This is part two of an article series about Ajax Portlet development. In my next post, i will tell you about how we handle inter-portlet communication in our framework and how our approach makes our application extremely flexible without hardcoding dependencies between portlets.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2009/01/using-yui-to-load-your-javascript-modules/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Selenium-Flex-Tests with Maven</title>
		<link>http://www.agimatec.de/blog/2008/11/selenium-flex-tests-with-maven/</link>
		<comments>http://www.agimatec.de/blog/2008/11/selenium-flex-tests-with-maven/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 19:05:05 +0000</pubDate>
		<dc:creator>Simon Tiffert</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[TeamCity]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=385</guid>
		<description><![CDATA[I wanted to integrate our Flex application with tests into our Maven build. A few days ago I moved the app to Flex 3 and changed the Maven Plugin from the Maven2 Flex Plugin to Flex-mojos. Now the artifacts are in the repository and you don&#8217;t need to install the Flex SDK to build the [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.agimatec.de/blog/wp-content/uploads/2008/11/img_2340.jpg" alt="" title="london" width="300" height="225" class="alignleft size-medium wp-image-390" />I wanted to integrate our Flex application with tests into our Maven build. A few days ago I moved the app to Flex 3 and changed the Maven Plugin from the <a href="http://www.israfil.net/projects/mojo/maven-flex2-plugin/">Maven2 Flex Plugin</a> to <a href="http://blog.flex-mojos.info">Flex-mojos</a>. Now the artifacts are in the repository and you don&#8217;t need to install the Flex SDK to build the application.</p>
<p>We have written the application as a demo in the first place and now wanting to test it in the wild. Because we use Cairngorm the application is well structured and contains as view layer only minimal parts of logic. Yes, we could include unit tests, but integration tests are far more interesting (from my point of view). In a large code base it could happen, that because of refactoring some things are broken. No deal, if you have tests and a CI system. But in the Flex app there are just tiny parts which I could test in a normal unit test.</p>
<p>Okay, so it should be integration test. Sounds good and not too complicated. There should exist a lot of frameworks because a lot of people start to use BlazeDS and other stuff in Java environments. Just something to start the app, run some tests and get the result back in the CI system.</p>
<p>I started to search on google and was surprised. Most of the blog posts I have found on that topic are just two month old. And there are not so many posts about that topic. With the combination of those posts I figured out, how to solve that problem. What problem?</p>
<ul>
<li>Integration tests of our Flex app</li>
<li>Integrated in Maven</li>
<li>Should work together with Cairngorm (would be more complicated with some unit tests frameworks)</li>
<li>Could be Selenium (to start the app and run tests)</li>
<li>Should be integrated in our continuous integration server TeamCity</li>
<li>Could be written in Java</li>
</ul>
<p><span id="more-385"></span></p>
<p>First thanks to the <a href="http://www.blackpepper.co.uk/black-pepper-blog/Flex-acceptance-testing-and-continuous-integration.html">blog post of Julia at Blackpepper</a>. She opened my eyes how to work with Java and Flex in combination. It is the combination of the SeleniumFlexAPI, which integrates as Flex to Javascript bridge in your Flex application and FlashSelenium.</p>
<p><a href="http://sourceforge.net/projects/seleniumflexapi/">SeleniumFlexApi</a> is in one part a Flex library which needs to be included in your app and on the other part an extension to the Selenium IDE. I like the Flex part, because it makes it easy to dive over Javascript into the details of your Flex app. What I don&#8217;t really like is the Javascript extension. Yes, it is not only a Selenium IDE part and you can include it into the start of the Selenium Server, but it is far away from Java and Maven.</p>
<p><a href="http://code.google.com/p/flash-selenium/">FlashSelenium</a> is a piece of code which let&#8217;s you talk from Java over Selenium with your Flex app. The Java part is very handy, but you need to code into Flex, which methods you could call over your bridge. So I need to write special code, which opens the bridge. The SeleniumFlexAPI is much better in this part.</p>
<p>I liked the solution of the blog post and started to implement it.</p>
<p>First the pom.xml where you need to include the SeleniumFlexAPI (the scope cost me some time):</p>
<pre class="xml" name="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;parent&gt;
        &lt;groupId&gt;agimatec&lt;/groupId&gt;
        &lt;artifactId&gt;assessor&lt;/artifactId&gt;
        &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
        &lt;relativePath&gt;../pom.xml&lt;/relativePath&gt;
    &lt;/parent&gt;

  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;groupId&gt;agimatec&lt;/groupId&gt;
  &lt;artifactId&gt;assessor-flexapp&lt;/artifactId&gt;
  &lt;packaging&gt;swf&lt;/packaging&gt;
  &lt;version&gt;${agimatec-assessor-version}&lt;/version&gt;
  &lt;name&gt;Assessor Flex Application&lt;/name&gt;
  &lt;url&gt;http://www.agimatec.de&lt;/url&gt;

  &lt;dependencies&gt;
    		 &lt;!--Flex SDK dependencies--&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.adobe.flex.sdk&lt;/groupId&gt;
			&lt;artifactId&gt;playerglobal&lt;/artifactId&gt;
			&lt;version&gt;3.0.0.477&lt;/version&gt;
			&lt;type&gt;swc&lt;/type&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.adobe.flex.sdk&lt;/groupId&gt;
			&lt;artifactId&gt;flex&lt;/artifactId&gt;
			&lt;version&gt;3.0.0.477&lt;/version&gt;
			&lt;type&gt;swc&lt;/type&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.adobe.flex.sdk&lt;/groupId&gt;
			&lt;artifactId&gt;framework&lt;/artifactId&gt;
			&lt;version&gt;3.0.0.477&lt;/version&gt;
			&lt;type&gt;swc&lt;/type&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.adobe.flex.sdk&lt;/groupId&gt;
			&lt;artifactId&gt;framework&lt;/artifactId&gt;
			&lt;version&gt;3.0.0.477&lt;/version&gt;
			&lt;type&gt;resource-bundle&lt;/type&gt;
			&lt;classifier&gt;en_US&lt;/classifier&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.adobe.flex.sdk&lt;/groupId&gt;
			&lt;artifactId&gt;rpc&lt;/artifactId&gt;
			&lt;version&gt;3.0.0.477&lt;/version&gt;
			&lt;type&gt;swc&lt;/type&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.adobe.flex.sdk&lt;/groupId&gt;
			&lt;artifactId&gt;rpc&lt;/artifactId&gt;
			&lt;version&gt;3.0.0.477&lt;/version&gt;
			&lt;type&gt;resource-bundle&lt;/type&gt;
			&lt;classifier&gt;en_US&lt;/classifier&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.adobe.flex.sdk&lt;/groupId&gt;
			&lt;artifactId&gt;utilities&lt;/artifactId&gt;
			&lt;version&gt;3.0.0.477&lt;/version&gt;
			&lt;type&gt;swc&lt;/type&gt;
		&lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;com.adobe.cairngorm&lt;/groupId&gt;
      &lt;artifactId&gt;cairngorm-bin&lt;/artifactId&gt;
      &lt;version&gt;2.2.1&lt;/version&gt;
      &lt;type&gt;swc&lt;/type&gt;
    &lt;/dependency&gt;

      &lt;dependency&gt;
        &lt;groupId&gt;org.openqa.selenium&lt;/groupId&gt;
        &lt;artifactId&gt;flex-api&lt;/artifactId&gt;
        &lt;version&gt;0.22&lt;/version&gt;
        &lt;type&gt;swc&lt;/type&gt;
          &lt;scope&gt;internal&lt;/scope&gt;
      &lt;/dependency&gt;

		 &lt;!--FlexUnit dependencies--&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;flexunit&lt;/groupId&gt;
			&lt;artifactId&gt;flexunit&lt;/artifactId&gt;
			&lt;version&gt;0.85&lt;/version&gt;
			&lt;type&gt;swc&lt;/type&gt;
			&lt;scope&gt;test&lt;/scope&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;flexunit.junit&lt;/groupId&gt;
			&lt;artifactId&gt;flexunit-optional&lt;/artifactId&gt;
			&lt;version&gt;0.85&lt;/version&gt;
			&lt;type&gt;swc&lt;/type&gt;
			&lt;scope&gt;test&lt;/scope&gt;
		&lt;/dependency&gt;
  &lt;/dependencies&gt;

  &lt;build&gt;
    &lt;sourceDirectory&gt;src/main/flex&lt;/sourceDirectory&gt;
    &lt;plugins&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;info.rvin.mojo&lt;/groupId&gt;
        &lt;artifactId&gt;flex-compiler-mojo&lt;/artifactId&gt;
        &lt;extensions&gt;true&lt;/extensions&gt;
        &lt;configuration&gt;
          &lt;includeSources&gt;
            &lt;param&gt;${project.build.sourceDirectory}&lt;/param&gt;
          &lt;/includeSources&gt;
          &lt;locales&gt;
            &lt;param&gt;en_US&lt;/param&gt;
            &lt;param&gt;de_DE&lt;/param&gt;
          &lt;/locales&gt;
          &lt;debug&gt;true&lt;/debug&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;info.rvin.mojo&lt;/groupId&gt;
        &lt;artifactId&gt;asdoc&lt;/artifactId&gt;
      &lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/build&gt;
&lt;/project&gt;</pre>
<p>To get the Flex application compile with Maven you need to download the SeleniumFlexAPI and include the swc-file into your Maven repository, because it is (not yet) available on public repositories.</p>
<p>After compiling you can start the Selenium IDE and load the extension or go directly to FireBug and try to call the methods. Be aware, that the args-parameter is normally optional, but needs to be filled for the Javascript-Flex bridge (also cost me some time).</p>
<p>To call a method of your running application in Firefox fire up in FireBug&#8217;s console:</p>
<pre class="html" name="code">window.document['AppName'].getFlexExists('NameOfAnElement','');</pre>
<p>To test your application you need to know, what the name of your application is (can be found in the HTML calling the Flash file) and you need to give ids to your elements, because there is just an id locator at the moment.</p>
<p>If you are at this point we can now switch to the Java part with Selenium. Selenium is just Javascript when you are in the browser. So all you do is to call the Javascript function which you called before over Firebug. FlashSelenium is a good wrapper for that call which means that you don&#8217;t have to write normal strings into your Selenium commands. I like a little bit more comfort and wanted to wrap the SeleniumFlexAPI a little bit closer. Also there are some methods in the FlashSelenium you don&#8217;t need with this solution. So I started to implement my own little wrapper. Maybe it is also interesting for the SeleniumFlexAPI (if completed with all methods).</p>
<p>Here is the beginning of the code:</p>
<pre class="java" name="code">package com.agimatec.assessor.selenium;

import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;

public class FlexSelenium {
    Selenium selenium;
    String flexApp;

    public FlexSelenium(String ip, int port, String browser, String url, String flexApp) {
        selenium = new DefaultSelenium(ip, port, browser, url);
        this.flexApp = flexApp;
    }

    public void start() {
        selenium.start();
    }

    public void open(String url) {
        selenium.open(url);
    }

    public void stop() {
        selenium.stop();
    }

    public String doFlexClick(String id) {
        return callFlexBridge("doFlexClick",id);
    }

    public boolean getFlexExists(String id) {
        return callFlexBridge("getFlexExists",id).equals("true");
    }

    private String callFlexBridge(String method, String id) {
        return callFlexBridge(method, id, null);
    }

    private String callFlexBridge(String method, String id, String args) {
        if(args == null || args.trim().equals("")) {
            args = "''";
        }
        return selenium.getEval("window.document['"+flexApp+"']."+method+"('"+id+"',"+args+");");
    }
}</pre>
<p>And now the test case is the only thing which is missing. I used TestNG because it can be easier configured in a Selenium environment (when it started to become more complicated with several browsers, plattforms, test suites, test groups &#8230;):</p>
<pre class="java" name="code">package com.agimatec.assessor.selenium;

import org.testng.annotations.Test;

public class AssessorTest {
    private final static String URL = "http://192.168.1.175:8080/assessor-webapp";
    FlexSelenium selenium;

    @Test
    public void setUp() throws InterruptedException {
        selenium = new FlexSelenium("192.168.1.254", 4444, "*firefox", URL, "Terminal");
        selenium.start();
        selenium.open(URL);
        while(!selenium.getFlexExists("videoPlayer")) {
            Thread.sleep(1000);
        }

        selenium.doFlexClick("videoPlayer");
        Thread.sleep(300);
        selenium.doFlexClick("enterUserModeButton");
        selenium.stop();
    }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/11/selenium-flex-tests-with-maven/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Advanced Javascript Namespaces for Portlets</title>
		<link>http://www.agimatec.de/blog/2008/10/advanced_javascript_namespaces_for_portlets/</link>
		<comments>http://www.agimatec.de/blog/2008/10/advanced_javascript_namespaces_for_portlets/#comments</comments>
		<pubDate>Tue, 28 Oct 2008 15:06:00 +0000</pubDate>
		<dc:creator>Sebastian Schuth</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Portlet]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=311</guid>
		<description><![CDATA[As mentioned earlier, we are doing some heavily ajaxified portlets over here at agimatec. When we switched to this Javascript-Centric Portlets, we had to solve a problem more people tend to have: The fundamental flaw of Javascript to depend on global variables for linking and the resulting clash of function names we wrote for our [...]]]></description>
			<content:encoded><![CDATA[<p id="mdq_"><a href="http://www.agimatec.de/blog/2008/08/selenium-testing-of-massive-ajax-apps/">As mentioned earlier</a>, we are doing some heavily <span id="tcls" class="misspell">ajaxified</span> portlets over here at agimatec. When we switched to this Javascript-Centric Portlets, we had to solve a problem more people tend to have: The fundamental flaw of Javascript to depend on global variables for linking and the resulting clash of function names we wrote for our portlets. There is a wildly-published way to handle this, which is not suitable when writing more than a few Javascript functions, and the way we handle this problem. But let&#8217;s start with a description of the commonly advised way of handling this problem and how that way falls short when doing serious Javascript in portlets.</p>
<h1 id="mdq_1">The easy way</h1>
<p id="mdq_2">When consulting the portlet books on the market or <a href="http://developers.sun.com/portalserver/reference/techart/ajax-portlets.html">Sun&#8217;s own tips</a>, you&#8217; gonna find one easy solution to the problem: using the portlet namespace for your Javascript. The portlet namespace is a portlet-instance specific string that is suitable to identify assets of a portlet instance. So the easy way out is to use it as prefix or post fix for the functions you write:</p>
<pre class="js" name="code">
&lt;!-- Example: JSP page --&gt;
&lt;%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %&gt;
<!-- ... -->
<script type="text/javascript">
    function doTerriblyUsefulStuff_
<portlet:namespace/>(){
        // your logic here
    }
</script>
<!-- ... -->
</pre>
<p id="mdq_4">Wow, that was easy. But there are some drawback when doing this:</p>
<ul id="mdq_5">
<li id="mdq_6">you have to stick to define your Javascript inside the portlets &#8211; no external Javascript files!</li>
<li id="mdq_7">being unable to define external Javascript files, there is no easy way of sharing Javascript code between portlets, which is not <a id="mdq_8" title="DRY" href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself" target="_blank">DRY</a></li>
<li id="mdq_9">Debugging gets even more painful with function names like &#8220;show_&lt;insert some lengthy string here&gt;()&#8221;</li>
</ul>
<p id="mdq_10">So, if your are up to make heavy use of Javascript and Ajax-based rich user interfaces, this is a <b>no-go</b>.</p>
<h1 id="mdq_11">Using external Javascript files</h1>
<p id="mdq_12">So, loading Javascript form external file is the way to go. So here is our approach to the problem:</p>
<h2 id="mdq_13">Use Javascript <span id="tcls4" class="misspell">namespaces</span></h2>
<p id="mdq_14">We are putting all our stuff into one global variable, called &#8220;agimatec&#8221; (at the time we chose the name, we were not aware of <a href="http://www.crockford.com/">Douglas Crockford</a>&#8216;s advice on making globals uppercase &#8211; otherwise we would haven named it &#8220;AGIMATEC&#8221;). This ensures that we&#8217;re leaving all third party scripts on the page untouched. Each portlet has its own (sub-)namespace inside this global.</p>
<h2 id="mdq_15">Use a convention to locate the script files</h2>
<p id="mdq_16">We&#8217;re putting our javascript files into a java-like folder structure that reflects our namespace structure, so the portlet &#8220;<span id="tcls5" class="misspell">Clientis</span> Edit User&#8221; is put into the namespace &#8220;agimatec.portlet&#8221; and the corresponding file can be found under &#8220;agimatec/portlet/clientisEditUser.js&#8221;</p>
<h2 id="mdq_17">Use a common initialization method for all portlets</h2>
<p id="mdq_18">All our portlet scripts must define the function &#8220;<span id="tcls9" class="misspell">getPortlet</span>()&#8221;, which returns a &#8220;raw&#8221; version of the portlet script.</p>
<h2 id="mdq_19">Let a library create portlet script objects</h2>
<p id="mdq_20">Last but definitely not least we have written our own library to create portlet instances. The library contains a function that takes the portlet namespace string, along with the name of the portlet Javascript object, creates a new instance by calling &#8220;<span id="tcls10" class="misspell">getPortlet</span>()&#8221; on the Portlet object and puts the instance into its own namespace which is created using the portlet namespace:</p>
<pre class="js" name="code">
/**
* Create a portlet namespace instance.
* @param {object} portletObject           A raw portlet namespace
* @param {string} portletNamespace    The Portlet ID as given by the portlet container
*/
agimatec.createPortletInstance(portletObject, portletNamespaceId){
    var rawNamespace = portletObject.getPortlet();
    portletObject[portletNamespaceId] = rawNamespace;
}</pre>
<p id="mdq_23">Using this technique, we are able to write clean, fully namespace-wrapped portlet scripts that have no problems with colliding function names and can co-exist even in multiple instances on one page without problems. As bonus, two instances of the same portlet on one page only load the external Javascript file once.</p>
<p>One major thing is not mentioned of this post: how to load the portlet scripts. We are using the <a href="http://developer.yahoo.com/yui/yuiloader/">YUI Loader</a> for loading the portlet scripts, amoung other things. I&#8217;ll cover this in another post in the next weeks, so stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/10/advanced_javascript_namespaces_for_portlets/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Selenium Testing of massive Ajax Apps</title>
		<link>http://www.agimatec.de/blog/2008/08/selenium-testing-of-massive-ajax-apps/</link>
		<comments>http://www.agimatec.de/blog/2008/08/selenium-testing-of-massive-ajax-apps/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 19:36:40 +0000</pubDate>
		<dc:creator>Simon Tiffert</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[Test]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=247</guid>
		<description><![CDATA[Testing of a web application is a hard work. You don&#8217;t handle with data in a direct way. You got a lot of markup around it. How to handle this in a flexible and more robust way could be found in the post Robust Portlet Testing. If you have fought your way through the markup, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-medium wp-image-249" title="img_25211" src="http://www.agimatec.de/blog/wp-content/uploads/2008/08/img_25211.jpg" alt="" width="300" height="225" />Testing of a web application is a hard work. You don&#8217;t handle with data in a direct way. You got a lot of markup around it. How to handle this in a flexible and more robust way could be found in the post <a href="http://www.agimatec.de/blog/2008/07/robust-portlet-testing/">Robust Portlet Testing</a>.</p>
<p>If you have fought your way through the markup, you now get to another trap on your way to get your tests flying. The markup is changing, because you are using the Ajax technology. After the page is rendered there are asynchronous calls changing your DOM. You are asking: Where is the problem? The problem of testing is, that you need to teach your test tool, to look at the page in the same way you are looking at it. On the first look you want to get the third row of the table. But wait, it is still loading, even if there is just a minimal delay. If you do automatic tests they should run through all the tests as fast as possible. The tool is not to twiddle one&#8217;s thumbs to click on the button.</p>
<p>You need to write your tests in another way. The question isn&#8217;t only if the data could be found in the DOM, it is changing to if the surrounding element has loaded could the data be found then. And this is the essential point, where most recording tools like Selenium IDE are failing. It doesn&#8217;t give you a hint, what is loading after the DOM is ready the first time. Yes it is possible to add pause or a waitForElement-function before every field, but wouldn&#8217;t it be easier to have little helpers for the case.</p>
<p><span id="more-247"></span></p>
<p>First let&#8217;s have a look at how the waitForElement-function in Selenium is working in Selenium-RC:</p>
<pre class="java" name="code">for (int second = 0; ; second++) {
    if (second &gt;= timeout) throw new ElementNotFoundException("Element not present: " + locator);
    try {
        if (this.isElementPresent(locator)) break;
    } catch (Exception e) {
    }
    Thread.sleep(1000);
}</pre>
<p>It is polling every second, if the element specified be the locator could be found. That is better than adding a pause. Why?</p>
<p>How long does your pause needs to be? 500ms, 1s, 2s? You are not sure about it, I am sure. It is a guessing and it is really slowing down your tests. You have 20 elements in one test. And let&#8217;s say you&#8217;ve got  50-100 tests at the beginning. Well &#8211; you are pausing damn long.</p>
<p>That&#8217;s why you should start using the waitForX-functions of Selenium. Now nearly every line of your massive Ajax test has a previous waitForX-function. It doesn&#8217;t make your tests more readable, but more stable and as fast as possible.</p>
<p>Now we are in a Java world, writing our Selenium tests and are tired of writing waitForX-functions. The next step is to extend the DefaultSelenium class and adding some tiny helper functions:</p>
<ul>
<li>safeOpen</li>
<li>safeGetText</li>
<li>safeGetValue</li>
<li>safeClick</li>
<li>&#8230;</li>
</ul>
<p>All these functions are equivalents of the normal Selenium functions, but having a waitForX-function build-in. Normally you are saying: getText for this element and giving a locator. Now use the locator to do a pre-test of the element. If the element could be found, get the text. It is just a little helper, but it makes your tests much cleaner and robust.</p>
<p>We have introduced another trick for the safeOpen function. Because we are fetching our dependend Javascript files asynchronously after the normal rendering has finished (check out the <a href="http://developer.yahoo.com/yui/yuiloader/">YUI Loader</a>), we add a new element with an id after the Javascript has finished its loading process. Now we can poll if the element is in the DOM and start after all the Javascript has loaded.</p>
<p>Check out the following example and try out how it helps to speed up writing your Ajax tests and reduce the test <em>to the test</em>.</p>
<p>See the following example test. Even if you don&#8217;t understand which application is tested, you can <em>read</em> the test:</p>
<pre class="java" name="code">    @Test(dataProvider = "users")
    public void testUserDetails(User user) throws InterruptedException, ElementNotFoundException {
        selenium.safeOpen(URL);

        // fill in search form
        selenium.safeType(
                browserXPath().elementByClassName("searchForm").textField().toString(),
                user.getUserIdentification());

        selenium.safeClick(
                browserXPath().elementByClassName("searchForm").submitButton().toString());

        // action to detail portlet with service menu
        selenium.safeClick(
                browserXPath().table().tr(1).td(1).a().toString());

        // check if all fields are available
        String[] userDetails = {user.getUserIdentification(), user.getGender().toString(), user.getFirstName(), user.getLastName(), user.getEmail(), user.getMobilePrefix(), user.getMobileNumber()};
        for (int i = 1; i &lt;= userDetails.length; i++) {
            selenium.waitForText(detailXPath().table().tr(i).td(2).toString(),
                    checkEmpty(userDetails[i]));
        }
    }</pre>
<p>To see the &#8220;<em>unbelievable magic</em>&#8221; behind the scenes, check out the <strong>AjaxSelenium</strong> extension:</p>
<pre class="java" name="code">
import com.thoughtworks.selenium.DefaultSelenium;

public class AjaxSelenium extends DefaultSelenium {
    public void safeClick(String locator) throws ElementNotFoundException, InterruptedException {
        this.waitForElement(locator);
        this.click(locator);
    }

    public void safeOpen(String pageUrl) throws InterruptedException, ElementNotFoundException {
        this.open(pageUrl);
        this.waitForPageToLoad("30000");
        this.waitForElement("//div[@id='javascript-loaded']");
    }

    public String safeGetText(String locator) throws ElementNotFoundException, InterruptedException {
        this.waitForElement(locator);
        return this.getText(locator);
    }

    public String safeGetValue(String locator) throws ElementNotFoundException, InterruptedException {
        this.waitForElement(locator);
        return this.getValue(locator);
    }

    public void safeType(String locator, String text) throws ElementNotFoundException, InterruptedException {
        this.waitForElement(locator);
        this.type(locator,text != null ? text : "");
    }

    public void waitForElement(String locator) throws ElementNotFoundException, InterruptedException {
        for (int second = 0; ; second++) {
            if (second &gt;= timeout) throw new ElementNotFoundException("Element not present: " + locator);
            try {
                if (this.isElementPresent(locator)) break;
            } catch (Exception e) {
            }
            Thread.sleep(1000);
        }
    }

    public void waitForText(String locator, String text) throws InterruptedException, ElementNotFoundException {
        for (int second = 0;; second++) {
            if (second &gt;= timeout) throw new ElementNotFoundException("Text '" + text + "' in element '"+ locator +"' not present.");
            try {
                if (text.trim().equals(this.getText(locator).trim())) break;
            } catch (Exception e) {}
            Thread.sleep(1000);
        }
    }

    public void waitForValue(String locator, String text) throws ElementNotFoundException, InterruptedException {
        for (int second = 0;; second++) {
            if (second &gt;= timeout) throw new ElementNotFoundException("Text '" + text + "' in element '"+ locator +"' not present.");
            try {
                if (text.trim().equals(this.getValue(locator).trim())) break;
            } catch (Exception e) {}
            Thread.sleep(1000);
        }
    }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/08/selenium-testing-of-massive-ajax-apps/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Robust Portlet Testing</title>
		<link>http://www.agimatec.de/blog/2008/07/robust-portlet-testing/</link>
		<comments>http://www.agimatec.de/blog/2008/07/robust-portlet-testing/#comments</comments>
		<pubDate>Mon, 28 Jul 2008 20:13:03 +0000</pubDate>
		<dc:creator>Simon Tiffert</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[Test]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=200</guid>
		<description><![CDATA[Testing of web applications isn&#8217;t easy. If you are in a portlet environment things getting even more complicated. A portlet is a web application for itself and there could be a lot of different combinations on every page. There could also be many instances of each portlet on a page. What are the consequences? You [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_202" class="wp-caption alignleft" style="width: 310px"><img class="size-medium wp-image-202" title="stonehenge" src="http://www.agimatec.de/blog/wp-content/uploads/2008/07/stonehenge.jpg" alt="Robust and durable" width="300" height="199" /><p class="wp-caption-text">Robust and durable</p></div>
<p>Testing of web applications isn&#8217;t easy. If you are in a portlet environment things getting even more complicated. A portlet is a web application for itself and there could be a lot of different combinations on every page. There could also be many instances of each portlet on a page.</p>
<p><strong>What are the consequences?</strong><br />
You couldn&#8217;t use normal ids on tags, because ids are unique on a page which conflicts when many instances of the portlet are on the same page.</p>
<p>A portal is themeable. The design and also the HTML structure depends on the user settings.</p>
<p>Portlets could be rearranged on a page, which means that the HTML structure is changing every time a new portlet is on a page or a portlet is moved to another place.</p>
<p><strong>Lessons we learned with portlet testing</strong></p>
<div id="attachment_208" class="wp-caption alignleft" style="width: 143px"><img class="size-medium wp-image-208" title="zen-stones" src="http://www.agimatec.de/blog/wp-content/uploads/2008/07/zen-stones.jpg" alt="Nice but unstable" width="133" height="144" /><p class="wp-caption-text">Nice but unstable</p></div>
<p>Try to write your tests as robust as possible. Nothing is as painful as seeing your test suite fallen to the ground.</p>
<p>You are developing a new theme or modifying your old one and all locators, in all tests, every field is broken.</p>
<p>You have a defined a set of portlets. Suddenly you need new portlets in this setup. You added the portlet at the top of the page and the tests are broken again.</p>
<p>Make portlet testing fun again.</p>
<p><strong>Using XPath the right way</strong></p>
<p>There are three tipps:</p>
<ul>
<li>Isolation</li>
<li>Wildcards</li>
<li>Abstraction</li>
</ul>
<p><strong>Isolation:</strong></p>
<p>Normally there is a surrounding div-container with an id of the portlet instance. Try to use this element as entry point for your XPath. If you use the generated XPath expression of a tool like Selenium IDE, XPath Checker or other tools you will never get structured expressions which are easy maintainable.</p>
<pre name="code" class="xml">
//div[@id='agimatec_portlet_curatorArcaeEdit__CuratorArcaeEditPortlet_WAR_ostiumcuratorarcae__editParcel']
</pre>
<p><strong>Wildcards:</strong></p>
<p>I have never seen a portal source code with a really clean html structure. Because there are many columns, many layouts, many supported browsers you end in a kind of tag soup. Yes you can get an XPath expression with 20 elements. As mentioned there are tools which are generating the expression, but one change and you are doing the work again. Use a kind of wildcards in XPath. With the isolation you are at the portlet instance and right into your own code. Maybe there is just one table inside the portlet, but a lot of more div-layers between the table. With the // syntax you can navigate recursive to the next child element of that type.</p>
<pre name="code" class="xml">
//div[@id='agimatec_portlet_curatorArcaeEdit__CuratorArcaeEditPortlet_WAR_ostiumcuratorarcae__editParcel']//table/tr[1]/td[2]
</pre>
<p><strong>Abstraction:</strong></p>
<p>Don&#8217;t write the same code again and again. Write a helper which constructs the XPath for you. If you use a framework to build your forms, you can write a library which navigates directly to the form elements. XPath expression aren&#8217;t fun. It is better that it hurts one person than the hole team. Strive for abstraction.</p>
<pre name="code" class="java">
detailPath().tab(1).ostiumTable().tr(1).td(2).toString())
</pre>
<p><strong>Conclusion</strong></p>
<p>There are a lot of tools for test recording. If you are using Selenium it is the Selenium IDE, if you use WebTest there is the WebTest Recorder. These tools are great for starting your web tests. But if your test suite is getting larger and you are working in an agile environment things are changing. Things are changing to often for maintaining recorded tests.</p>
<blockquote><p>Learn with recorders but test with logic</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/07/robust-portlet-testing/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Cache refresh</title>
		<link>http://www.agimatec.de/blog/2008/07/cache-refresh/</link>
		<comments>http://www.agimatec.de/blog/2008/07/cache-refresh/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 21:05:43 +0000</pubDate>
		<dc:creator>Simon Tiffert</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=193</guid>
		<description><![CDATA[Caching is one of the important aspects if you are dealing with larger AJAX applications. You have a lot of Javascript, Images, CSS and static HTML. Just a part of it is static and the rest will be the same until the next deployment. What you are doing is forcing the browser to hold as [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.agimatec.de/blog/wp-content/uploads/2008/07/brain.jpg"><img class="alignleft size-medium wp-image-194" title="brain" src="http://www.agimatec.de/blog/wp-content/uploads/2008/07/brain.jpg" alt="" /></a>Caching is one of the important aspects if you are dealing with larger AJAX applications. You have a lot of Javascript, Images, CSS and static HTML. Just a part of it is static and the rest will be the same until the next deployment. What you are doing is forcing the browser to hold as many files as possible on the client side and just fetch the dynanic parts of the application. If you don&#8217;t know how to achieve this, have a look at the following posts: <a href="http://www.agimatec.de/blog/2008/05/schritt-fur-schritt-zur-schnelleren-web-anwendung/">Step by Step to a faster web application</a> or <a href="http://www.agimatec.de/blog/2008/05/caching-mittels-http-header/">Caching with HTTP Header</a> (german).</p>
<p>The solution is great, we have reduced the requests to the Tomcat to a minimum (in our case less then 10%). Javascript is cached, CSS is cached, images are cached. But wait, we have do deal with updates and bugfixes. The files are now spread to hundred clients &#8211; deep burned into the brain with a far Expire HTTP header. This means if there is no manual refresh the files are there until Christmas, and will maybe survive the next Spring Break. We need a solution to get a clean update, on <em>all</em> client browsers.</p>
<p><span id="more-193"></span></p>
<p>What you need is a <em>fresh</em> URL for your files. The browser compares the URL and if there is a new URL inside the HTML it will be loaded. In our case the HTML is dynamic and won&#8217;t be cached, that&#8217;s why we don&#8217;t need to care about it. Our problem are the resource files (Javascript, CSS, images). To get a fresh URL for your files you need to answer the following question: What is the difference between two software version? Yes, you are right, the version number. So you need to include the version either in the path or in the file name. Because this is mainly a Java blog I hope you manage your files with a build tool like Ant or Maven. The first idea was to introduce the version number in the path and move folders with a Ant task to the new path before they are packed as WAR file. This worked for one folder but in our application we are dealing with a lot of portlets. Portlets are registered in the portal container and couldn&#8217;t be easily renamed. A solution would be to add the version number to all of folders inside the portlet but that&#8217;s sound like a lot of pain.</p>
<p>We need another solution, a solution that fits whenever a cached file is called which shouldn&#8217;t be reloaded. I followed a talk of Andrea Provaglio about AOP in web applications in the Java User Group Cologne two weeks ago. The main conclusion was: <em>Whenever </em>you say <em>whenever </em>- you should think about solving your problem in a kind of aspects. But how to solve our problem? The solution is a servlet filter. The files can still be deployed in the normal way but we can do a little bit of URL rewriting magic inside a filter. For the caching I&#8217;m using a servlet filter to set the Expire header. I extended this filter that there could be a version number given in the init-parameters. This version number is removed from the request and forwarded to the default file.</p>
<p>For this solution I need just a few steps:</p>
<ol>
<li>The servlet filter with URL rewriting</li>
<li>The filter definition with version number as init-param in the web.xml</li>
<li>Resource calls with the version number included</li>
</ol>
<p>Let&#8217;s have a look at the solution:</p>
<p><strong>Before</strong>:</p>
<p><em>http://www.agimatec.de/blog/example.css</em></p>
<p><strong>Now</strong>:</p>
<p><em>http://www.agimatec.de/blog/example-2.3.4-SNAPSHOT.css</em></p>
<p><strong>Future</strong>:</p>
<p><em>http://www.agimatec.de/blog/example-8.9.10.css</em></p>
<p>The file has changed but is deployed to the same location /blog/example.css as before. The servlet filter has the version number (2.3.4-SNAPSHOT) and removes it from the call. What we get on the server side is the same call as before. With a new deployment we just need to increase the version number and wait for the download of the new version of the file.</p>
<p>Do you also need a solution for this problem? Maybe the following code could be a starting point for you:</p>
<pre name="code" class="java">
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CacheFilter implements Filter {
    private FilterConfig filterConfig;

    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // get the http servlet request
        final HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        final HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;

        // set Expires header for optimized caching
        String cacheTime = filterConfig.getInitParameter("cache-time");
        if (cacheTime != null &#038;&#038; !cacheTime.trim().equals("")) {
            httpServletResponse.setDateHeader("Expires", new Date().getTime() + Long.parseLong(cacheTime));
        }

        // get the url of the original request
        String url = httpServletRequest.getServletPath();

        String version = filterConfig.getInitParameter("version");

        // if there is a version info configured, try a forward
        if (version != null &#038;&#038; !version.trim().equals("")) {
            // remove the version info
            String redirectUrl = removeVersionInfo(url, version);

            // if there is a difference in the url
            if (!url.equals(redirectUrl)) {
                // forward the call to the new url
                servletRequest.getRequestDispatcher(redirectUrl).forward(servletRequest, servletResponse);
                return;
            }
        }

        // normal call if there is no forward
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }

    public void destroy() {
        filterConfig = null;
    }

    public static String removeVersionInfo(String url, String version) {
        if (version != null &#038;&#038; url != null &#038;&#038; !url.trim().equals("")) {
            url = url.replaceAll(Pattern.quote(version), "");
        }
        return url;
    }
}
</pre>
<p>Questions, suggestions, errors? Write a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/07/cache-refresh/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
