<?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; Portlet</title>
	<atom:link href="http://www.agimatec.de/blog/tag/portlet/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>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>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>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>
	</channel>
</rss>
