0



28Jun2013

How AgileSites simplifies Fatwire/Sites development

In this post I want to explain the underlying ideas behind AgileSites.
The goal is not only showing what it does but also why and how it performs its magic.
In theory you may also apply the ideas in this article without using AgileSites itself, although I believe the simplest path is just download and use it if you like the approach. There are no strings attached: the framework is Open Source and Apache Licensed (so you can use it in your  commercial project without having to release any code).

Simplifying Sites Coding

Everything starts when a Java developer looks at this piece of  JSP code (the typical code you have to deal with when you code for Fatwire/Sites)
<assetset:setasset name="as"
   type='<%= ics.GetVar("c")%>'
   id='<%= ics.GetVar("c")%>'/>
<assetset:getattributevalues
   name="as"
   listvarname="ls"
   attribute="Title"/>
<ics:listget
   listname="ls"
   fieldname="value"
    output="Title">
<%= ics.GetVar("Title") %>

All of this coding is needed just to read an attribute. Code is so verbose because it uses JSP tag libraries. Tag libraries are not really designed to implement a complex business logic, only simple rendering logic in a form readable (and editable) by people who cannot (or does not want)  code (for example HTML designers).
As many people point out, XML (and thus HTML) is not a programming language, and if it were, it would be verbose and unreadable. This code is a typical example of a simple task becoming complex because the tool is meant for a different purpose.   What this code does, after all, is just retrieving an asset and then extracting an attribute from it.
A Java/OOP developer would immediately say: the intermediate IList used is a technical detail that can be hidden inside some object, and many parameters (like "c" and "cid") can be considered implicit, so they do not need to be expressed.
So  if we were using Java, you would define a couple of classes and  the code could become as simple as:
e.getAsset().getString("Title")
Indeed this is how attribure retrieving looks in AgileSites, and  this simplicity is one of the (many) benefits it provides. The problem here is to understand how it reaches this goal.

Switching back to Java

The first idea to simplify Sites coding is to use a  library. In plain Fatwire/Sites you can do something like this:
<ics:callelement name="Lib/ReadAttribute">
  <ics:argument name="attribute" value="Title">
  <ics:argument name="source" value="as">
</ics:callelement>
Indeed many people uses a library of reusable elements to automate attribute retrieval. The result however  is not much more readable than before, only slightly shorter; but elements (because  they are not really meant to be an OOP construct) have problems like changing the enviromnent with sometimes unwanted side effects. There are thus drawbacks when using a library of elements.
A plain Java class as a library is much better. So why not use it? Indeed AgileSites defines a couple of classes similar (but more complex than) to those:
class Asset {
  String getString(String attribute)
}
class Env {
   Asset getAsset()
}

Internally the Env.getAsset() actually performs the assetset:getasset and stores the result in the class instance (code is optimized to load the assetset object only once).  The Asset.getString()  actually uses the assetset:getattributevalues to retrieve the attribute (code is optimized to load attributes lazily).
All of this is not a great magic for a Java coder. The difficult part is how to write Java code in the JSP-only world of Fatwire/Sites environment, invoking  using Java tje API available only as JSP tags...

Java coding in a JSP world

Writing code in Java is not uncommon in the Sites development world. The real problem is that the process is not dynamic and productive enough. In J2EE world if you add a Java class to the webapp, you need to redeploy it  to be able to see changes in Java code. Because all of this is pretty time consuming, Fatwire/Sites developers does not do this very often, and instead just rely on JSP (stuffing a lot of java code in it).
AgileSites strives to be agile, so  instead of asking the developer to redeploy the application for each change,  it does its magic with a core library that can load dinamically a jar built continuosly  without restarting the application server.
It is important to note that this ability is not new at all in the Java world. Applets has been working this way for ages: they  load in the browser a Java application packages in a jar from the net, and a browser restart is not needed. Indeed, since the ability to load a jar is built into Java from version 1.0, AgileSites uses the Applet class loader to load such a jar.
So your code can be just plain Java. Templating is done with the Picker keeping the view in pure HTM;  I will cover this feature in another post. You code your business logic in full, uncrippled, clean  Java. Then your code is compiled on the fly and packaged in a jar and it is  available for execution putting the shell in continuos compilation mode.
When you invoke a template, the jar is reloaded (only if it is changed) and then your code can be executed.  This way your java coding is as dynamic as JSP coding but you do not have to use the crippled java offered by JSP.
The whole trick is explained in this Architecture diagram:

Invoking tags from Java

The next problem is writing code that can actually use JSP tags. Fatwire provides a Java API for asset manipulation but many functions are only provided as a JSP tag. Actually JSP tags in Fatwire/Sites are only a proxy for invoking the internal Sites API (really the one designed for use with the XML tags)  exposed through the ICS facade. However invoking a tag  with ICS is pretty awkward. This is why AgileSites provides a layer for simplifying access to tags.
When AgileSites is built, it will inspect the Tag Library Definition  of Fatwire/Sites to build a  wrapper library to access tags from java. Using this wrapper library there is a direct mapping from a tag to a java call, than can be show with a simple example. A tag invocation like:
<asset:load name="a" type="Page" objectid="123456"/>
is translated directly in Java as:
AssetTag.load().name("a"").type("Page").objectid("123456").run(e.ics);
Using this library for example the retrieval of an attribute can be implemented  with this following code (equivalent to the assetset:getattributevalues but  encapsulated in a clean java class).
  public String getString(String attribute) {
          return e.getString(at(attribute), "value");
  }
  private String at(String attribute) {
           String attrList = attribute.toUpperCase();
           if (i.GetList(attrList) == null) {
                  String attrType = e.getConfig()
                     .getAttributeType(ics.GetVar("c"));
                  AssetsetTag.getattributevalues().name(as)
                      .attribute(attribute)
                      .listvarname(attrList)
                      .typename(attrType).run(i);
            }
            return attrList;
  }

If you read this sample you should be able now to understand fully how is possible that the complex  JSP coding of the first example can became the simpler Java of the second  example.

However AgilesSites offers more: for example  the pure-html templating . Stay tuned for the next post if you are interested.

 

Posted by msciab
28Jun2013