Pigs Don’t Fly

October 13th, 2009

A few posts back, I discussed my new project, an online quiz application, and the initial choice of GWT and GXT as the framework. The article was entitled “Pigs are Flying”, due to my previous convictions and statements that were not always kind to so called Rich Internet Applications.

Well it turns out after all that pigs do not fly and GWT/GXT does not fly.

A few caveats here. I use GWT daily in my consulting gig, so I have some experience in the area. I just remain a firm believer in applying Ajax judiciously. GWT (and certainly GXT) is full blown Ajax, almost HTML-less Ajax, if that is possible.

I still stand by the heuristic that an RIA will take twice as long to develop as the comparably functional Ajax-enhanced HTML application. Does this type of application have a place? Most definitely. Just be certain you requirements dictate such a tool and you have the funding and or time for its implement. In my situation, I just did not have such a luxury, particularly to wait around for applications to reload changes and to search out documentation on a less than fully documented third party framework.

Nuff said on that issue.

Since I’ve always been a user of Spring, and I initially started prototyping the quiz app in Spring MVC, I returned to SpringSource technologies, but not Spring but Grails.

I may have a little to say about Grails in the future (and I don’t like to repeat what is already said out there) but Grails is truly excellent.

While pigs are not flying anymore (although they are trying to take off, since I’ve also had some less than kind things to say about dynamic languages) there is still much to get used to in a language like Groovy. I specifically mean the lack of static type checking. However, IntelliJ does a decent job with things like code completion. Plus the dynamic application reloading is great. It’s nice not to hit the restart button after every code change.

That’s it for the status update. I’ll return to discussing performance issues in future articles. I find it hard not to get sidetracked when the topic of framework selection and evaluation arises.

 

HttpSession and GWT

September 1st, 2009

Most anyone who has done Java server programming has dealt with the Session object, as well as its siblings (and I use that term in essence, not in fact) objects: ServletContext, HttpRequest and HttpResponse. Of course, if you are using a newfangled “Component” framework that tries to “shield” you from the intricacies of HTTP, you may not be familiar with these babies.

GWT is somewhat of a mélange of both Component frameworks and Request/Response frameworks. It is certainly on the component side of the spectrum, in that you are programming mainly in Java objects and using Swing-like constructs and events. But that is mainly on the client side of things. On the server side, GWT is strictly Servlet based, with some excellent marshalling thrown. The marshalling is so good that sometimes can make you forget the HTTP underpinnings. A dead giveaway, other than of course reading the documentation, is that any remote service must be defined in web.xml as a Servlet. I always found this odd, since most newer request /response frameworks(that gladly expose HTTP constructs) tend to use a single “Base” Servlet that you then must extend. Typically, you would create a single Servlet Mapping for this Base Servlet, which would handle essentially all requests. The Base Servlet, based on some xml, annotated, convention based, or a combination of the above, would pass control to a custom Java class which would handle the actual implementation. The Base Servlet and related framework will also provide much of the “plumbing” and other features, such as parameter object mapping, view integration, etc.

With GWT, every remote service you make available to the client must be defined as a distinct Servlet in web.xml (I feel like I’ve already said this, but it is worth repeating). The Servlet class defined is actually the developer’s specific java class, not a base Servlet. This class must extend RemoteServiceServlet, which is a descendent of HttpServlet. This is a key point in the discussion that will follow. Beware of a framework that forces you to extend its own classes (Ok, for the few of you in the know, XX Framework makes you do this as well, but I plead ignorance since I didn’t know better at the time. And I hadn’t seen Spring MVC yet).

Begin a Servlet, our GWT remote service implementation has access to all the HTTP goodies, specifically HttpSession, which I at one time said this post was about. To access the HTTP Session, you use the method

getThreadLocalRequest().getSession()

If this was a HttpServlet Sevice() method, you’d have access to this directly via the HttpServletRequest parameter . But since that method is long gone by the time your code is called, GWT stores this information and makes it available in a ThreadLocal object. ThreadLocal is a construct that lets each JVM thread have its own version of any class level variables. GWT needs ThreadLocal since a Servlet, as in HTTPServlet, needs to serve multiple threads. TheThreadLocal makes data available to all threads that may be accessing that Servlet.

Now remember the following point:

Each Servlet maintains its own ThreadLocal storage

There is nothing unusual with this. How else could multiple threads be served?

The problem arises when you decide to treat your Remote Service Implementation as just another Java class (POJO anyone) and not what it truly is, an HTTPServlet.

So the problem arises when any server side GWT code instantiates a GWT Remote service implementation directly.

Why is this a problem? Well in most cases, it may not be. We won’t include bad architecture in this discussion, which that most certainly is. The problem occurs when you try to access our old friend, getThreadLocalRequest().

The Remote Service Serlvet’s, which our Implemenation must extend, private ThreadLocal storage is initialized when the HTTP Service (POST, GET) happens. The HttpServletRequest, which includes the HttpSession is stored in the Servlet’s Threadlocal storage for access by the current thread.

When that Remote Service Implementation, or any other subsequent code, instantiates another Remote Service Implementation, the new Service’s ThreadLocal is created (it has to be as we are creating a new object) but it is not initialized, since no HTTP Get or Post has occurred. Therefore, any access to getThreadLocalRequest() will throw a NullPointerException, as this information has not yet been stored in ThreadLocalStorage.

I recently hit this problem while working with a client’s code. Doing an internet search and looking at some GWT books didn’t really shed any light on the problem. The only mention was a simple description, useful nonetheless, of the basic method for accessing the HttpSession and related objects. No warning or discussion of what happens when you instantiate a new Remote Service Servlet implementation object.

This is another reason why the SpringSource guys are being proved right time and time again. Please check out Spring MVC for an example of a web framework that can use pure POJO’s for most functionality. These POJO’s can be subsequently instantiated and used, as they have no dependency on the framework.

Implementing GWT, Pigs are Flying

August 11th, 2009

I’ve always promoted a “standards” oriented approach to web development, meaning, a server side app that produces pure XHTML, styled with CSS, with Ajax added where appropriate. I’ve worked with GWT for some time and feel, while it is a tremendous product, it is essentially VB (ok maybe closer to Swing) for the web/JavaScript. It excels at building a desktop application look and feel. Contrast this with a more “web” look and feel, especially some of the sites associated with web 2.0.

I haven’t written a post for some time. I’ve been debating what client tool to use on quiz application. I originally planned on using Flex, figuring I could do a nifty interface and still integrate with Spring and Java on the back end. I also did some quick prototyping of CRUD screens in Spring MVC. It is amazing how easy it is to get simple HTML forms and data entry working  with that framework. I really like it and the philosophy behind it.

However, whenever I do HTML based apps, there is always the missing piece which is graphic design. I will admin that is not my strong point. I can do a passable job (see Domuswap.com archive), but it is not something that comes quick and easy to me. I would sure love to spend time learning photoshop, etc. I have no doubt that there are some nice approaches to easily styling HTML, I just haven’t stumbled across one that works for me yet.

So far, I can really get into Flex. I felt I was jury rigging the thing to get it to speak to Java/Spring. I wish Springsource would release an integration layer with GWT. I am sure it is coming. Not that is was that much work, but it is much more involved that what I’ve been doing for the past year with GWT. The client and server integration is so tight, you sometimes don’t realize on what side of the app you are.

The final blow came when I explored the excellent GWT add on library/framework, Ext GWT. The Web Desktop demo really blew me away. It is really just some nice CSS, but that is really important. The look of an application is the majority of it’s appeal.

I’ve always held that a major benefit of GWT is that it lets graphics impaired developers put together a good looking application. I think I may go down that path, or should I say, towards the dark side.

Always Start with the Use Cases

July 25th, 2009

You usually come into any project with somewhat of an idea of what you want the thing to do. The first step, therefore, is to get these ideas down on paper. This process can encompass a mission statement, feature list, or other textual description of what you want to get done. We are in the brainstorming phase here, so anything you write is good. Let the ideas flow.

Now when you are ready to sit down and actually begin work (making sure your coffee cup is filled first) the first step should be use case diagramming. We are still in the brainstorming phase at this point, but use cases make the application begin to take shape, with early definitions of actual application components emerging.

Many of the use cases will be obvious. Some will become evident once the more obvious ones are defined. For use cases, there will certainly be “view available quizzes”, “take quiz” and of course some sort of authentication / log in behavior.

The initial data model can be developed in parallel with the use cases. Remember, both of these models will evolve throughout the life of the project. We are not doing big upfront design here, just enough architecture to get going. But some formal design is always a good idea.

As you go through the use case modeling, keep a note of the domain objects that you start describing. Start building your domain / class model now as well. Some of these will be obvious. In my cases, things like Quiz, Answer, Question, and of course the always present object User, were things I didn’t need to think much about. But the relationships between the two are not obvious. Is user related to quiz, quiz to question, or is there something more complex going on.

As soon as a few main uses cases are defined, it is time to jump into coding. Besides the fact that this is what I like to do, early coding will help you solve early problems and answer unknowns related to new technologies. You just want to make sure you are on the right track. This is called the vertical slice approach, where you build out a piece of functionality, generally a couple of use cases, from start to finish (from the web page to the database, the full stack). Plus it is always nice to have a working application to show. I won’t go into a full discussion of this topic. Just see any of the Agile literature for more information.

The quiz application is not yet an earth shattering innovation (but I do have a few things planned that could very well be). However, one goal is to implement the latest best practices in web application development. As such, I finally have the luxury to take the time and do it right. Of course, there are time pressures for this one as well, there always are. Even if there aren’t any dictated timelines, technology will eventually move ahead, you can’t stop that, and you will always be chasing the latest and greatest technology and practices.

The Complete Rewrite

July 19th, 2009

Have you ever worked on a project and not thought that is would really benefit from a complete rewrite? It would be nice if that was not the case, but I believe reality dictates that what we wind up releasing is less than ideal.

One reason for this is changes in technology. New tools, techniques, and frameworks are constantly being developed. How many projects out there using Struts would not prefer a rewrite in a more modern framework.

The second reason is time constraints. We just do not always have the time to implement things the way we would like in the ideal world. There is always pressure to get things done yesterday. Much of programming wisdom is in finding the right balance between quick development and a well designed application, and delivering as much of both as possible.

We also seem to like the complete rewrite, such as when a new release of a product comes out. Check out this announcement from Spectral Core for their excellent Full Convert product.

Full Convert 5.0 released:

1-Conversion engine rewritten so that .NET framework is no longer required. This considerably reduces installation size and memory consumption, improves conversion speed and user interface responsiveness.

I feel good about this new feature, after all, it is a complete rewrite.

When I wrote Domuswap, I didn’t have the luxury of a complete rewrite. Domuswap was developed concurrently with the XX framework 1.1 and 2.0. Once the framework proved successful in Domuswap, it was released. However, I was still using the underlying framework and legacy code. Some was rewritten, but the time certainly wasn’t there for a complete rewrite. Indeed, I was very happy with how easily the existing code fit into the Spring MVC components that were added.

Would I have liked to do a complete rewrite? Definitely. I’d probably like to prove that XSL could indeed be speedy, or get rid of that approach entirely. I’d also like to enhance the multi threading techniques. I did this to some extent for version 2.0, in conjunction with my Sarasota Java Users Group presentation on concurrency. But that feature is still in experimental stages.

If I was to do a complete rewrite of the XX Framework, I would probably start with pure Spring MVC and just weave in some of the more interesting XX features, all the while sticking to their interfaces as much as possible.

All that being said, I find myself with the luxury of doing a complete rewrite at this very moment with the New Project. I plan to do this, in addition to satisfying the necessary functionality, as an implementation of what I see as the current best practices in web application development. I’ll have much more to say about this project in future columns.

The New Project

July 15th, 2009

I began a new project today. We’ll really last weekend; I am just getting to write about it now.

The projects not in relation to my current full time consulting gig (which is a GTW project for the insurance industry). The new project will be an education testing program for a local community college, essentially online quizzes. I am also using this project as an opportunity to explore new tools and frameworks.

When we think education application, Flex comes to mind, and it is certainly a frontrunner, especially for the interface/testing component and if multimedia is incorporated.

For the back end, I am moving away from the XX Framework. While I think the framework is awesome, I need to get additional experience on more industry standard tools. Of course, XX is built on Spring MVC. But I want to get some additional experience in pure Spring apps.

Spring Web Flow is another possibility. The more I read about Spring MVC and Spring web flow, the more in common I see with what is in the XX Framework. Regarding Web Flow, I don’t know if I want to write so much in their XML/Expression based DSL. I don’t mind specifying this stuff for control reasons (like what XX does) but getting into defining variables doesn’t seem the place for XML based grammars.

Spring web flow does lend itself to a graphical editor. I haven’t tried Spring IDE, but since they were a recent SunJug sponsor, I took a quick spin in Skyway Builder , an eclipse based GUI for generating Spring MVC/Spring Web Flow apps. It is really an impressive product. However, being impressive doesn’t mean it is useful (sort of how I feel about GWT most of the time). Why try to graft a GUI over what is a perfectly capable and expressive language (Java / XML). In some cases, this will make sense, but in many or most, just writing plain old Java is quicker and quite understandable.

I need to work more with these tools to really make a judgment on them, however.

The one thing I always start with is a bit of upfront UML modeling. I use Enterprise Architect, which is a really inexpensive and reasonable good UML tool. Just brainstorm out the use cases and draw up some classed. It always helps to diagram these out before putting them to Java , and it doesn’t take too long to get to the Java stage.

One thing I did take away from reading some of the Web Flow docs was the use of UML state diagrams. I have always used Use Case diagrams and activity diagrams almost exclusively, but the web flow authors showed how State diagrams can more easily model the overall flow of the entire applications.

So I will most certainly do a Spring MVC / Hibernate / MySQLback end. Build out the model and services. I haven’t decided on the front end. It may be Flex, with BlazeDS or web service interface. Maybe JSF, which I have the least experience in and would like to learn. Most likely a portion will be in a Spring MVC view technology, namely JSF, Velocity, or Freemarker. Most likely, the application wills involve several of the above tools.

Java Versus PHP

July 12th, 2009

One of my main interests is in web frameworks, or more simply put “what is the best way to implement a given application?”.

I like Java, love the IDE’s available and what they can do, and believe that a good Object Oriented design is the foundation of a good application, irrespective of the technologies used.

That being said, there are some really great PHP applications out there (Wordpress, Joomla. Drupal, etc). You really can’t point to as many open source, easily available Java applications.

The main selling point of the PHP is the ease of installation and deployment. Most of the popular programs just require you to upload the source code and run an installation script.

Java on the other hand is a bit more involved. If all goes well, you should just be able to copy a War or Ear file to your server and you are all set. Of course, there are issues with restarting the application and such architecture is of questionable ease to extend with plug-ins the way PHP seems to be. I’d like to think that all the good Java developers are too busy building really cool corporate applications, which might actually be the case.

I bring all this up due to my recent experience in finalizing the XX Framework. I have two demo applications that are part of the distribution, a guestbook and an implementation of Java Pet Store. I’ve successfully converted these to XX 2.0, and they can easily be deployed as a War file.

My intention was to have the demos available online. This is always a nice to have when looking at a new framework or product.

I use and love Eapps.com for hosting. I’ve been able to run Domuswap.com on their shared VPS environment, but soon outgrew them and moved to a GoDaddy dedicated box.

Since I don’t want to spend much money to keep the demo apps online, I attempted to deploy the War to a shared 256MB server. It deployed and ran fine, but quickly blew through available CPU, so I had to back it out before I received a phone call from Eapps support “suggesting” that I upgrade.

I thought, if this was a PHP application, it would likely work fine and be quite fast. Is this just the nature of PHP versus Java, PHP being more suitable for the low end and Java more for the high end. I think this is probably the case. I should add, that the XX framework is a known CPU hog, being entirely dependent on XSL transformation and those can certainly spin up the processor.

I’d like to compare apples to apples some day and deploy a simple and lean Java app, with and without additional frameworks like Spring and Hibernate. I could rewrite the demos to do this and hopefully someday I will have the time to do just that.

XX Framework V2.0 is Released

July 8th, 2009

After several years of work, the latest release of the XX Framework is now available.

The major change to the framework is that it is now ported to SpringMVC. This should allow greater flexibility and easier incorporation into existing or new Spring applications.

One of the first comments I heard when I released the framework back in 2006 was “how does this differ from Spring”. I didn’t think it was much like the Spring core, but he must have meant SpringMVC. Over the years, Spring MVC turned out to be one of the few frameworks that made perfect sense in almost every manner (as does Spring itself). Much of the early work on XX, and most frameworks, is in developing the plumbing (servlet routing, data marshalling, transactions, security, etc). This was all built into XX, but Spring already does it and much better I am sure.

A while back, I made the decision to port the framework to sit on top of SpringMVC and let it handle all the plumbing and let XX do what Spring does not: automatically marshall data from the web layer to the database layer and back, and provide an XSL centric view paradigm.

The migration was surpisingly smooth and would have happened much sooner if I can the time or additional resources. After the servlet mapping layer was migrated, most of the XX controller and database functionality just worked as is. The one main change I made was to incorporate Spring Hibernate integration (DAO stuff) and dependency injection.

The framework has powered Domuswap.com, in both its Spring and pre-Spring incarnations. While a site’s performance is certainly related to the hardward available, we did get some 4000 visitor days at its peak.

I still think the key differentiators of the XX framework continue to be valuable. Further integration into Spring is needed to where it is more of a plug in to Spring rather than a separate framework built on top of Spring (like Grails).

Check out the XX Framework.

Caching in the XX Framework

July 7th, 2009

I am reprinting this older blog post on Caching in the XX Framework. It is still relevant, though I would prefer to get the basic documentation up first.

The following discussion example uses guestbook sample, on the XX framework web site. http://xxframework.org/guestbook/ListGuestbook. This non-cached page will be converted into a cached implementation.

Let’s look at the structure of the page displayed when the URL listed above is requested.

The page is divided into 5 components. This can be best illustrated by looking at the XX config file.

ListGuestbook.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE xx_config SYSTEM “http://www.xxframework.org/dtd/xx_config.dtd”>

<xx_config newthread=”true usepool=”false poolcheck=”10000“>

<classes>

<class id=”3 scope=”page use=”xsl applyxsl=”true“>

<classname>org.xxframework.control.RecordControl</classname>

<method>get</method>

<hb_classname>org.xxframework.searchfilter.Dummy</hb_classname>

<xsl_file>AddMessage.xsl</xsl_file>

<security secure=”false“>

</security>

</class>

<class id=”4 scope=”page applyxsl=”true use=”xsl“>

<classname>org.xxframework.control.RecordControl</classname>

<method>get</method>

<hb_classname>org.xxframework.searchfilter.GuestbookFilter</hb_classname>

<xsl_file>ListGuestbookFilter.xsl</xsl_file>

<security secure=”false“>

</security>

</class>

<class id=”5 scope=”page applyxsl=”true use=”xsl timeout=”20000“>

<classname>org.xxframework.control.RecordControl</classname>

<method>list</method>

<hb_classname>org.xxframework.guestbook.entity.Message</hb_classname>

<xsl_file>ListGuestbook.xsl</xsl_file>

<security secure=”false“>

</security>

</class>

<class id=”1 scope=”page applyxsl=”true use=”xsl“>

<classname>org.xxframework.control.RecordControl</classname>

<method>list</method>

<xsl_file>mainmenu.xsl</xsl_file>

<security secure=”false“>


</security>

</class>

<class id=”2 scope=”page use=”file applyxsl=”false“>

<endpoint>[xmlroot]/../../guestbookmenu.html</endpoint>

<security secure=”false“>

</security>

</class>

</classes>

<jsp>searchlist.jsp</jsp>

</xx_config>

Referring the guestbook page (http://xxframework.org/guestbook/ListGuestbook), the 5 components implement the following functionality

Class id Description
1 Login Box. This box will change, based on the login state of the user
2 Left side menu, below login area. This section doesn’t change
3 The new message text entry in the top center
4 The message search area in the middle center
5 The guestbook message list. This will be the most dynamic and resource intensive component of the page.

The other components of the page (top menu and header graphics) are included in the JSP page indicated in the config file (searchlist.jsp). Note that the JSP page can include dynamic and well as static content. In this case, the content is static.

The caching behavior is described by the “scope” attribute of the class element. The valid scope values are the following:

Value Description
page No caching
session Cached at user session level
application Cached at application level, for all users

Since all classes have page scope, no caching takes place in the ListGuestbook servlet.

If the 5 classes above, classes 2, 4, and 5 can be cached at the application level, since all users should see the same text when browsing this page. Classes 1 and 3 are user specific. Class 1 section will change from a login to a logout button depending on the logged in status of the user.

Class 3 may not be that obvious. While not really necessary, the author text box will default to the user’s user id, if logged in. If not logged in, author text box will maintain any previous value entered by that user. For a logged in user, this information is available in the XML request document. For a non-logged user, this information is maintained in the user’s session. Therefore, for classes 1 and 3, session level caching is appropriate.

To implement the caching needed, modify the scope attribute of the class element, as follows.

<classes>

<class id=”3 scope=”session use=”xsl applyxsl=”true“>


</class>

<class id=”4 scope=”application applyxsl=”true use=”xsl“>


</class>

<class id=”5 scope=”application applyxsl=”true use=”xsl“>


</class>

<class id=”1 scope=”session applyxsl=”true use=”xsl“>


</class>

<class id=”2 scope=”application use=”file applyxsl=”false“>


</class>

</classes>

The class element may also take an optional “timeout” attribute. The value of this attribute represents the time, in milliseconds, when the cache should automatically be expired.

Given a config file as above, classes 2, 4, and 5 (application level) will only be called once. Afterwards, the html values will be read from application memory (servlet context actually). Classes 3 and 5 will be called once for each user. Afterwards, the values will be read from session memory.

Leave the system in this state, however, will cause a potential problem: once generated, the pages will never change. This is not a problem for classes 2 and 4. These sections will only change when the menu for search box changes. In our case, these sections are static. If our search box contained a company pull down, for instance, the search section would need to be updated whenever a company is added or deleted.

The other page sections, however, will not remaining static. Most obvious is class 5, the message list itself. This will change whenever a message is added or deleted. Since deletion is not part of the guestbook sample, let’s consider the case when a message is added. If the cache is not updated, the new message will not show up. To fix this problem, we must look at all the use cases that could cause the cache to need to update. In the case of the guestbook application, the add message use case will invalidate the saved message list.

The add message use case is implemented by the SetMessage servlet servlet. This servlet uses the SetMessage.xml XX config file. Here is the relevant portion of that config file

SetMessage.xml

<class id=”3 use=”xsl scope=”page applyxsl=”true“>

<classname>org.xxframework.control.RecordControl</classname>

<method>set</method>

<hb_classname>org.xxframework.guestbook.entity.Message</hb_classname>

<error_pattern>&lt;xx_error</error_pattern>

<error_jsp>main.jsp</error_jsp>

<error_xsl>reply.xsl</error_xsl>

<security secure=”true“>

<role name=”Administrator mode=”any“/>

<role name=”* mode=”add“/>

</security>

</class>

To control caching we add a “cache_control” element.

SetMessage.xml

<class id=”3 use=”xsl scope=”page applyxsl=”true“>

<classname>org.xxframework.control.RecordControl</classname>

<method>set</method>

<hb_classname>org.xxframework.guestbook.entity.Message</hb_classname>

<error_pattern>&lt;xx_error</error_pattern>

<error_jsp>main.jsp</error_jsp>

<error_xsl>reply.xsl</error_xsl>

<security secure=”true“>

<role name=”Administrator mode=”any“/>

<role name=”* mode=”add“/>

</security>

<cache_control>

<cached_page name=”ListGuestbookCache.xml“>

<id>5</id>

</cached_page>

</cache_control>

</class>>

</class>

This new element states that when this class is successfully executed, clear the cached values for the indicated pages, represented by the XX config file name and class id within the config file.

In the case of the SetMessage use case, class 5 in the ListGuestbookCache config file (the message list) is cleared. The next time the ListGuestbookCache page is called, the message list will be regenerated.

The remaining two classes in the ListGuestbookCache use case are session level caches. The first, class 1 changes when the user logs in or out. Therefore, we can clear the cache for that class on the login and logout use cases. These use cases are represented by the Logon.xml and Logoff.xml file. The appropriate cache_control elements are added to these two configurations

Logon.xml


<class id=”4 scope=”page applyxsl=”true use=”xsl“>

<classname>org.xxframework.control.Login</classname>

<method>get</method>

<hb_classname>org.xxframework.basetypes.User</hb_classname>

<xsl_file>Logon.xsl</xsl_file>

<cache_control>

<cached_page name=”ListGuestbookCache.xml“>

<id>1</id>

</cached_page>

</cache_control>

</class>

Logoff.xml


<
class id=”4 scope=”page applyxsl=”true use=”xsl“>

<classname>org.xxframework.control.Login</classname>

<method>set</method>

<xsl_file>Logoff.xsl</xsl_file>

<cache_control>

<cached_page name=”ListGuestbookCache.xml“>

<id>1</id>

</cached_page>

</cache_control>

</class>

Returning to the ListGuestbookCache use case, class 3, the add message area, hasn’t yet been handled. This text box needs to change when the user adds a message, or when the user logs in and out. Therefore, we need to clear this case on user login/logout, and on add message. This can be accomplished by adding a cached_page element to the existing cache_control element. The following changes complete our requirement of clearing the cache in the appropriate situations

SetMessage.xml

<class id=”3 use=”xsl scope=”page applyxsl=”true“>

<classname>org.xxframework.control.RecordControl</classname>

<method>set</method>

<hb_classname>org.xxframework.guestbook.entity.Message</hb_classname>

<error_pattern>&lt;xx_error</error_pattern>

<error_jsp>main.jsp</error_jsp>

<error_xsl>reply.xsl</error_xsl>

<security secure=”true“>

<role name=”Administrator mode=”any“/>

<role name=”* mode=”add“/>

</security>

<cache_control>

<cached_page name=”ListGuestbookCache.xml“>

<id>5</id>

</cached_page>

<cached_page name=”ListGuestbookCache.xml“>

<id>3</id>

</cached_page>

</cache_control>

</class>

Logon.xml

<class id=”4 scope=”page applyxsl=”true use=”xsl“>

<classname>org.xxframework.control.Login</classname>

<method>get</method>

<hb_classname>org.xxframework.basetypes.User</hb_classname>

<xsl_file>Logon.xsl</xsl_file>

<cache_control>

<cached_page name=”ListGuestbookCache.xml“>

<id>1</id>

</cached_page>

<cached_page name=”ListGuestbookCache.xml“>

<id>3</id>

</cached_page>

</cache_control>

</class>

Logoff.xml

<class id=”4 scope=”page applyxsl=”true use=”xsl“>

<classname>org.xxframework.control.Login</classname>

<method>set</method>

<xsl_file>Logoff.xsl</xsl_file>

<cache_control>

<cached_page name=”ListGuestbookCache.xml“>

<id>1</id>

</cached_page>

<cached_page name=”ListGuestbookCache.xml“>

<id>3</id>

</cached_page>

</cache_control>

</class>

Additional notes on Caching

In addition to the class id and scope, caching is specific to the parameters of a given request. For a show user user case, we would not want showuser?id=6 to use the same cache as showuser?id=7. But we would want all calls to showuser?id=6, executed by any user, to use the cached result.

Internally, XX uses the request parameters to distringuish the two so the appropriate result is returned.

XX Framework 2.0 is finally released!

July 6th, 2009

I’ll have more information in the next few days, but I’ve uploaded all the files to Sourceforge.

These files include the actual framework source , in Jar form and in the form of a simple Hello World Web App. I also updated the two demo programs, Guestbook and Petshop.