Thursday, June 26, 2014

Porting to Foundation: Handling HTML5

Introduction

This post will focus on extending the Spring form tag lib.  As I discussed in my prior post we need to enhance the attribute handling of this library to utilize HTML5 input facilities in our application.

Most of the HTML5 attributes are traditional name value pairs and with the dynamic attribute handling provided by the current tag library this is sufficient for most of the new attributes. However there are a couple of attributes, specifically 'required' and 'autofocus', that we need to omit from the rendering if not needed.  For example if we attach the 'required' attribute and set it to false on an input element (required="false") that field will still be required.  To correctly generate HTML5 requires that we extend the Spring WebMVC form tag library to handle these attribute.

Fortunately, we will only need to extend a limited subset of the tags from the current form tag library.  The 'required' and 'autofocus' attribute handling needs to be injected into input, textarea, checkbox and select tags.  Implementing this functionality is not exceeding difficult.  To implement we need to;
  • Define the new tag library definition file (TLD file) containing the definitions of the tags we are extending.
Then for each tag we must;
  • Provide an implementations of the extended behavior.
  • Modify the tag definition to reference the extended class and add the new attributes we are extending.
  • And finally modify the tagx file to use the extended tag.

Defining the Tag Library File

The first step is to get the newly custom tag library functional is the creation of the tag library file definition.  This piece ties the Java implementation that we need to provide later to the tags in the JSP.

The tag definition library must be placed in the WEB-INF folder.  For the purposes here we need to make a copy of the Spring form tag library definition file and edit it to fit our needs.  A complete explanation of custom tag libraries is out of our focus here.  As mentioned before only the input, checkbox, select and textarea tags need to be extended so the first edit on this file should be to remove all the other tags to reduce its size.

Provide the Extended Tag Behavior

Then for each of the remaining tags we need to change the tag-class to reference the extended Java implementation of that class.  For example here is the Java class for the input tag;;

package com.springsource.petclinic.tag;

package com.springsource.petclinic.tag;

import javax.servlet.jsp.JspException;

import org.springframework.web.servlet.tags.form.InputTag;
import org.springframework.web.servlet.tags.form.TagWriter;

public class HTML5InputTag extends InputTag {

 private static final long serialVersionUID = 1L;

 private String required;

 private String autofocus;

 private String min ;
 
 private String max ;
 
 public String getAutofocus() {
  return autofocus;
 }

 public String getMax() {
  return max;
 }

 public String getMin() {
  return min;
 }

 public String getRequired() {
  return required;
 }

 public void setAutofocus(String autofocus) {
  this.autofocus = autofocus;
 }

 public void setMax(String max) {
  this.max = max;
 }

 public void setMin(String min) {
  this.min = min;
 }

 public void setRequired(String required) {
  this.required = required;
 }

 @Override
 protected void writeOptionalAttributes(TagWriter tagWriter) throws JspException {
  if (TextUtils.isTrue(required)) {
   writeOptionalAttribute(tagWriter, "required", "true");
  }
  if (TextUtils.isTrue(autofocus)) {
   writeOptionalAttribute(tagWriter, "autofocus", "true");
  }

  if (!TextUtils.isEmpty(min)) {
   writeOptionalAttribute(tagWriter, "min", min.trim());
  }
  
  if (!TextUtils.isEmpty(autofocus)) {
   writeOptionalAttribute(tagWriter, "max", max.trim());
  }

  super.writeOptionalAttributes(tagWriter);
 }

}


Here the custom input extends the Spring provided implementation adding a collection of new attributes and exposing it by offering getter and setter methods.  To handle the rendering the class overrides the writeOptionalAttributes method.  This method is invoked during the rendering of the tag and allows the attributes to be optionally injected into the resulting markup.

With the extension of the input class I have also included handling of the 'min' and 'max' attributes.  Unlike the 'required' and 'autofocus' attributes these attributes are injected into the markup only if not null or empty strings.  Adding these attributes allows streamlining of those attributes in the input.tagx file.

Modify the Tag Definition

Now we need to modify the tags definition in the tag definition file (TLD) that we created earlier.  There are two updates to the tag that need to made.  First the tag-class element needs to reference our newly implemented tag extension class.  And second we need to add the attribute definitions for the new attributes being handled.

Here is the resulting tag definition for the input tag;

 <tag>
  <description>Renders an HTML 'input' tag with type 'text' using the bound value.</description>
  <name>input</name>
  <tag-class>com.springsource.petclinic.tag.HTML5InputTag</tag-class>
  <body-content>empty</body-content>

  <!-- a bunch of attribute definitions omitted here >

  <attribute>
   <description>HTML5 Attribute</description>
   <name>required</name>
   <required>false</required>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
  <attribute>
   <description>HTML5 Attribute</description>
   <name>autofocus</name>
   <required>false</required>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
  <attribute>
   <description>HTML5 Attribute</description>
   <name>min</name>
   <required>false</required>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
  <attribute>
   <description>HTML5 Attribute</description>
   <name>max</name>
   <required>false</required>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
  <dynamic-attributes>true</dynamic-attributes>
 </tag>


Modify the input.tagx File

The last part of the implementation is to modify the tagx file to use the extended tag.  Doing this requires that we change the 'form' namespace declaration to refer to the extended tag library definition rather then the Spring provided one.

Here is the root element definition from the input tagx file as generated by Roo;

<jsp:root xmlns:c="http://java.sun.com/jsp/jstl/core" 
 xmlns:fn="http://java.sun.com/jsp/jstl/functions" 
 xmlns:spring="http://www.springframework.org/tags" 
 xmlns:form="http://www.springframework.org/tags/form" 
 xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">



And here is the modified element;

<jsp:root xmlns:c="http://java.sun.com/jsp/jstl/core" 
 xmlns:fn="http://java.sun.com/jsp/jstl/functions" 
 xmlns:spring="http://www.springframework.org/tags" 
 xmlns:html5="urn:jsptld:/WEB-INF/html5-form.tld"
 xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">


Now in the input element we have to refactor the form namespace elements to use the new namespace.  It is also here where the new functionality of the tag library can now be utilized.  In the original application the form:input tag code has;

              <form:input id="_${sec_field}_id" path="${sec_field}" disabled="${disabled}" />

Now in that code we can write;

<html5:input id="_${sec_field}_id" type="${type}"
 path="${sec_field}" disabled="${disabled}"
 required="${required}" pattern="${validationRegex}"
 minLength="${min}" maxLength="${max}" min="${minDecimal}"
 max="${maxDecimal}" step="${step}" />


The application tagx files can now take full advantage of the new HTML5 goodies, including the 'required' attribute..  What remains to be done at this point is providing similar implementations for all the input controls that we identified earlier.  With mix-ins this would be a snap but unfortunately right now we have to maintain some similar code.

This leads us to the end of this section.  My next post will proceed from here and continue the implementation for HTML5 tags for the pet clinic application.

Connecting Spring Security Authentication to Domain Entities

Introduction

With about every consumer facing web application today the need to allow users to create and maintain accounts within the web application is a requirement.

Spring Roo provides the ability to integrate Spring Security into web applications readily via a simple installation command.  By default the scaffold-ed implementation provides a rudimentary authentication implementation configured in the applicationContext-security.xml file.  It looks like this;

    <!-- Configure Authentication mechanism -->
    <authentication-manager alias="authenticationManager">
        <!-- SHA-256 values can be produced using 'echo -n your_desired_password | sha256sum' (using normal *nix environments) -->
        <authentication-provider>
            <password-encoder hash="sha-256" />
            <user-service>
                <user name="admin" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" authorities="ROLE_ADMIN" />
                <user name="user" password="04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c85b9df8fb" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>

    

This of course is inadequate for production use, except for exceptional cases.  What we need is a convenient way to integrate the web applications entity model, again scaffold-ed by Roo, with the Spring Security infrastructure.

What we need is for Spring security to authenticate using our web application entity model.  Doing this is simple, there are two main parts of the solution.  First, we need to implement the user data interface that consumed by Spring security to access the application domain model.  And course we need to reconfigure the security application context to use that implementation.

Spring security uses a component that implements UserDetailService as the source of user information.  We need to provide an implementation that uses our web applications entity model as the source of user data.  Again there are two tasks needed to accomplish this.  First we need to provide a implementation of the expected component.  And we must design our application user entity (or AppUser) to provide the needed data.

The AppUser must provide minimal authentication data, username and password.  But there are additional features available like, account, credential locking, and expiration features that the application may want to integrate with.  Supporting a majority of these features can be done trivially utilizing Roo's scaffolding, with the exception of passwords.  But why should that be a surprise.

Encoding Passwords

Everybody knows clear text passwords should never be stored.  When authenticating Spring Security expects the password provided by our application to be encoded.  To encode passwords we need to use the same password encoder implementation that  the security infrastructure uses.  There are multiple implementations of encoders some more easily cracked then others.  But of course higher security usually translates in more computing and operating costs.  However keep in mind changing the algorithm used by the application will invalidate all existing passwords so careful up front selection is advised since changing this once in service will impact user experience.

When saving passwords in the AppUser object we need to encode the password.  Via Spring configuration we can set the encoder that the security infrastructure will utilize.  Additionally, that will allow auto wiring the encode into application code.  Using the encoder is simply just a matter of passing the clear text password to the encode method to obtain the encoded password.  From this point it is just a matter of including the encoding functionality when storing passwords.

Here is my controller handles the user registration.  Note there are two parts of the code that participate in the encoding password process.  First the auto wiring of the 'encoder' bean into the controller so it can be accessed.  Then later in the code when setting the password the encoder is utilized to do the encoding.

package com.repik.buddyframework.web;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.hibernate.exception.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.roo.addon.web.mvc.controller.scaffold.RooWebScaffold;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.repik.buddyframework.domain.AppUser;
import com.repik.buddyframework.domain.Profile;
import com.repik.buddyframework.domain.ProfilePreferences;

@RequestMapping("/appusers")
@Controller
@RooWebScaffold(path = "appusers", formBackingObject = AppUser.class)
public class AppUserController {

 @Autowired
 private PasswordEncoder encoder ;
 
 @RequestMapping(value = "/register", method = RequestMethod.POST, produces = "text/html")
    public String register(@Valid AppUser appUser, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {
        if (! bindingResult.hasErrors()
          && appUser.getPassword().equals(appUser.getConfirmPassword())
          && appUser.getEmail().equals(appUser.getConfirmEmail())) {
         try {
             uiModel.asMap().clear();
             appUser.setAccountNotExpired(Boolean.TRUE);
             appUser.setAccountNotLocked(Boolean.TRUE);
             appUser.setAuthorities( "Guest");
             appUser.setCredentialsNotExpired(Boolean.TRUE);
             appUser.setEnabled(Boolean.TRUE);
             
             // set the password to the encoded hash value
             appUser.setPassword( encoder.encode( appUser.getPassword()));
             
             appUser.persist();
             return "redirect:/login" ;
         }
         catch ( JpaSystemException jse ) {
          Throwable cause = jse.getCause() ;
          boolean handled = false ;
          while ( cause != null ) {
           if ( cause instanceof ConstraintViolationException ) {
                  bindingResult.addError( new FieldError("appUser", "username", "username already taken" ));
                  cause = null ;
                  handled = true ;
           }
           else {
            cause = cause.getCause() ;
           }
          }
          
          if ( ! handled )
           throw jse ;
         }
        }

        populateEditForm(uiModel, appUser); 
        return "appusers/register";
    }
 
    @RequestMapping(value ="/register", params = "form", produces = "text/html")
    public String registerForm(Model uiModel) {
        populateEditForm(uiModel, new AppUser());
        return "appusers/register";
    }

    
}

Implementing the UserDetailsService

Next we need to provide an implementation of the UserDetailsService.  Spring Security uses this component to obtain user details.  We our implementation to access the application user domain object rather then the default implementation.

The implementation is pretty simple.  The UserDetailsService interface requires a single method, loadUserByUserName, where the usage is a user name is provided as a string and the component should return a UserDetails object for that user.  While is was tempting during implementation to allow the AppUser domain object itself implement this interface, instead to keep things simple this implementation uses a data transfer object instead.

The logic just involves finding the AppUser by username, then if found populate a User instance to return to the Spring Security infrastructure.  The first part of the implementation will be to create a finder to allow finding AppUsers by username.  This is done will in the Roo shell with the following command;

focus --class ~.domain.AppUser
finder add --finderName findAppUsersByUsernameEquals

Now the UserDetailsService implementation can be completed;

package com.repik.buddyframework.domain;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.persistence.TypedQuery;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class AppUserDetailsService implements UserDetailsService {

 @Override
 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  
  TypedQuery<AppUser> appUsers = AppUser.findAppUsersByUsernameEquals(username);
  AppUser appUser = appUsers.getSingleResult() ;
  return appUser == null 
    ? null 
    : new User(appUser.getUsername(), 
      appUser.getPassword(), 
      appUser.getEnabled(), 
      appUser.getAccountNotExpired(),
      appUser.getCredentialsNotExpired(),
      appUser.getAccountNotLocked(),
      getAuthorities( appUser.getAuthorities())) ; 
 }
 
 private Collection<? extends GrantedAuthority> getAuthorities( String authorities ) {
  if ( authorities == null ) {
   return null ;
  }
  
  List<GrantedAuthority> result = new ArrayList<GrantedAuthority>() ;
  
  String[] tokens = authorities.split( "\\W" ) ;
  for ( int i = 0 ; i < tokens.length ; i++ ) {
   result.add( new SimpleGrantedAuthority(tokens[ i ])) ;
  }
  
  return result ;
  
 }


Configuring the Security Application Context

All now that remains is to configure Spring security to utilize the new implementation of the UserDetailService.  The configuration is contained in the 'applicationContext-security.xml' file.  Specifically towards the end of the file we need to configure the authentication provider to use our implementation of the UserDetailService.  Note also that the encoder bean is defined here allowing the use within the application context.

    <!-- Configure Authentication mechanism -->
    <authentication-manager alias="authenticationManager">
  <authentication-provider user-service-ref="customUserDetailsService">
   <password-encoder ref="encoder"/>
  </authentication-provider>
    </authentication-manager>

    <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/&gt
    
<beans:bean id="customUserDetailsService" class="com.repik.buddyframework.domain.AppUserDetailsService" />

Now the implementation is complete.  Most of our effort in the implementation here really centered around integrating our AppUser domain object to provide the user data conform to that required Spring Security.

Sunday, June 15, 2014

Revisiting the Design of Restful Service API's

As part of an on going side project, I've been building a couple of services into a web site that handles images provided by guests of the application.  For production we need to manage these images, involving cleaning them up and optimizing them for delivery to the presentation.

First during the upload service we will need to prepare the image for handling by the application.  Then during viewing the service layer will needs to provide different renderings of the image as required by the application presentation.

Subsequently the application will need a image service to provide this functionality.  This image service will need to allow the presentation layer of the image to request the size of the image.  Also in production it is almost certain that this service will be cached.

So the question arose what is the best practice for handling service arguments for RESTful services?  In our example here we have three arguments; the id of the image along with the width and height of the image.  With the id argument the decision is straight forward, it should be part of the URL.  However with the width and height arguments things are not so simple. Should it be a query parameter or a path segment in the URL?

There are pluses and minus's to either route.  Putting path segments in the URL presents problems when arguments are optional.  The nature of the services response changes for handling missing results depends also on how the argument is passed. When passing arguments as a path segment the service should return a 404 status, while with query parameters and empty result set should be returned.

This in turn leads to the question of 'What are the best practices for determining how to send service arguments to the service layer of the application'?

While seeking that answer I ran across this on Stacktrace.  This is a great response in the sense that it provides a framework for determining how data is passed to the service layer given the type of data.

Late answer but I'll add some additional insight to what has been shared, namely that there are several types of "parameters" to a request, and you should take this into account.
  1. Locators - E.g. resource identifiers such as IDs or action/view
  1. Filters - E.g. parameters that provide a search for, sorting or narrow down the set of results.
  1. State - E.g. session identification, api keys, whatevs.
  1. Content - E.g. data to be stored.
Now let's look at the different places where these parameters could go. 
  1. Request headers & cookies
  1. URL query string ("GET" vars)
  1. URL paths
  1. Body query string/multipart ("POST" vars)
Generally you want State to be set in headers or cookies, depending on what type of state information it is. I think we can all agree on this. Use custom http headers (X-My-Header) if you need to. 
Similarly, Content only has one place to belong, which is in the request body, either as query strings or as http multipart and/or JSON content. This is consistent with what you receive from the server when it sends you content. So you shouldn't be rude and do it differently. 
Locators such as "id=5" or "action=refresh" or "page=2" would make sense to have as a URL path, such as mysite.com/article/5/page=2 where partly you know what each part is supposed to mean (the basics such as article and 5 obviously mean get me the data of type article with id 5) and additional parameters are specified as part of the URI. They can be in the form of page=2, or page/2 if you know that after a certain point in the URI the "folders" are paired key-values. 
Filters always go in the query string, because while they are a part of finding the right data, they are only there to return a subset or modification of what the Locators return alone. The search in mysite.com/article/?query=Obama (subset) is a filter, and so is /article/5?order=backwards(modification). Think about what it does, not just what it's called! 
If "view" determines output format, then it is a filter (mysite.com/article/5?view=pdf) because it returns a modification of the found resource rather than homing in on which resource we want. If it instead decides which specific part of the article we get to see (mysite.com/article/5/view=summary) then it is a locator. 
Remember, narrowing down a set of resources is filtering. Locating something specific within a resource is locating... duh. Subset filtering may return any number of results (even 0). Locating will always find that specific instance of something (if it exists). Modification filtering will return the same data as the locator, except modified (if such a modification is allowed). 
Hope this helped give people some eureka moments if they've been lost about where to put stuff!


Here is the link to the original page;

http://stackoverflow.com/questions/4024271/rest-api-best-practices-where-to-put-parameters

Cheers!

Friday, February 7, 2014

A Strategy for Assembling Enterprise Web Applications

I have been rethinking web development.

Most web development is focused on building and maintaining the 'site'.  These 'sites' are massive, it's no wonder things go wrong.  Architecturally, SOA didn't change a lot in terms of site scale and complexity, offering some value while becoming another man in the middle.  But still the 'site' must do all business processes that the consumer interacts with.

For each business process on each site there is a corresponding implementation, and each of those implementations are different,  Additionally every one of these implementations requires its own separate development and maintenance track.  Getting enterprise wide changes replicated across the brands web presence is a slow process.  Building web sites this way results in an incredible amount of duplicated effort and waste.

My solution strategy presented here takes a different approach.

Instead my strategy is to build smaller components each representing a business process.  Where a component would offer a silo of functionality including web resources for containing applications. Components can offer forms and widgets for inclusion by the containing application. These components then could be used across brands in addition to multiple sites within a brand.  For example within a booking component we might find widgets for making payments, creating and modifying bookings.

We must recognize that there won't be a 'site' but rather an ecosystem of sites, most undoubtedly deployed on a cloud infrastructure.  A brand digital presence is represented by the collection of web applications the consumer interacts with.  And as with anything consumer facing those applications should be able to react quickly to changes in the customers behavior.  In this type of environment agility determines how quickly a organization can react to changes in its environment.

Application Assembly

With components organized along business lines assembly of web applications can be rapid.  Where assembling of a web applications consists of defining the container, and adding the components needed.  From there the remaining task is to define the page layouts.



Providing an implementation that allows modular construction of web applications like this is remarkably easy.  Conversion into a modular web component consists of moving the view definitions into the /META-INF folder.

With this strategy then the minimal structure of a web application would be;
  • A business process component -- this component would provide tiles definitions, controllers, and tags to enable a business process.  
  • A brand component, this component would provide cross brand layout and style design elements associated to a brand.
  • Site specific component, this component provides the application container and is responsible for application launch.  

An actual production deployment application would require multiple business process and infrastructure components (security, content) to be complete.

Component Structure

To tie these components together to provide a coherent site we need to follow an extensible structure.

 Rather then reinvent we can use applications generated by Spring Roo.  This is an excellent scaffold to structure our applications on.  First the application is an modular framework, adding and removing models is built into the scaffold.  Additionally a huge advantage is Roo's code development assistance, allowing the agile development of business functionality.  Repetitive cross enterprise development operations could also be automated using Roo's add on capability.




This scaffolding along with the SpringMVC infrastructure provides the usual Spring IOC infrastructure, along with component scanning for controllers and tiles view definitions.  The result is a component that can offer;
  • Tiles definitions - During startup the Spring WebMVC does a web resource path scan looking for tiles definition files.  These definition files allow for registering of views offered by the module.
  • Tags - Custom tags expressed in JSP can now be exposed for consumption by the containing application.  For example a check in status widget could be placed on a page using a tag.
  • Controllers - during component scan controllers will be registered with Spring WebMVC.  Components can offer services associated with a request.
  • Aspects - scaffolding structure makes injecting functionality via aspects easier and more structured.  
Using Spring Roo as the scaffolding provider we can sketch out applications quickly.  Take for example the PetClinic application, this application can be up and running within a half hour and that is with rudimentary security.

I will explore building modular web components in more detail in future posts.  An important part of this strategy is re-skinning the applications constructed by Roo to provide responsive design.  This work is part of another track Porting Roo Web MVC ApplicationsTo Foundation.

Regards


Thursday, December 19, 2013

Porting Roo MVC Applications to Foundation

Introduction

One of the areas I have been exploring is the structure of web applications generated by Spring Roo.  These are Spring WebMVC application and result in a tightly structured application.  But the WebMVC is only part of the solution.  The add-on provides the view definitions using a nicely structured tag library and bases it's view definitions on these.  Of course part of the structure is result of Roo's code generation facilities, and that does enforce a regularity of the application structure.

Currently the rage in web design is flat responsive web applications.  At work it seems that everyone is in love with Foundation, and truly there is a lot to love about it.  It's a snap to layout forms and pages.  Prototyping is a breeze.  One can build nice looking pages without tip toeing into CSS hell.  But most importantly it is responsive allowing your application to not only look decent but to look decent on multiple devices.
Petclinic Home Page - Desktop Browser

The Spring WebMVC applications generated by Roo are nice, practical, but not responsive.  Available within Roo however there is the GWT front end that does have support for mobile.  But that again is not responsive.since mobile and desktop are separate sets of responses.  On the server side we really want to stick with being responsive so we can avoid having to inject functionality to handle multiple device responses.

As part work on another post I have been working on exploring the Spring WebMVC structure.  While working on that post I have been thinking that it wouldn't be hard to port an application to use Foundation.  So I decided to do a proof of concept on that.

Design


Petclinic on iPhone 5
(Ripple Emulator)
When the WebMVC is installed in the application it injects two kinds of assets; those that are managed such as the CRUD views of domain objects, and those that are injected during setup an under the developer management.  Most of the files that fall in the latter category is application framework (tiles defs, etc), view components (header, footer) and system views (exceptions, index).  The migration should be limited to the modification of those assets.  Ideally, we should be able to leave the assets managed by Roo alone so Roo can continue to manage them for us.

Generally in the migration we are going to want to limit changes to;

  • tiles layout assets (default.jspx, header.jspx, footer.jspx, load_scripts.jspx).
  • The tag library (*.tagx) files.  
And we want to avoid making changes to;
  • tiles definition files,
  • view files
  • controllers, etc.

Results

In porting the site to Foundation the efforts focused on three areas;
  • Page Layout and Navigation
  • Forms and Fields
  • Tables

I will dive into the fine details in future posts, but here I want to present an overview of my experience migrating the pet clinic application to use Foundation.

Page Layout and Navigation

Page layout while setting the stage for things to come was not that hard to migrate.  Fortunately the Roo WebMVC placed all the loading of the Javascript in a tag so moving it from the head to the end of the body was simple.  Most of the effort required here was not so much implementing the new layout as to finding and selecting a new design.  There are quite a few really sharp looking public domain layouts to choose from so some time on the Intenet is well worth it  After fishing around for a while I settled on using layout from the Foundation web site.

Getting the menu to run was also really simple, largely because both implementations are based on a unordered list.  So most of the effort here was changing styling and the handling of categories of menu items.


Then after a few adjustments to components here and there I got the home page working.

Then looking at the home page using iPhone 5 emulation with Ripple;


And here it is with the hamburger open;


There are a few rough areas like the footer that require more work.  But generally the result is a presentable site.  The Spring WebMVC theme handling is broken, but shouldn't be hard to fix.

One of the goals in my POC was to minimize change occurring in the vews folder.  I ended up deleting the header.jspx file, it was injecting a page wide image breaking the responsiveness of the pages.  But the changes here were anticipated.  More importantly we did not modify the index.jspx file.  Since having to make changes here would be indicative of having to make changes to all the  view files.  Something we really want to avoid..

In my next post I will look at forms and fields.




Tuesday, October 29, 2013

More On the Simplifying Development Of Addons

In my last post on simplifying add on development all the exposed mechanics of building class (or interface) structures was driving my nuts.  One of the things I don't like about Roo is the API.  However the beauty of open source is I can do something about that.  It's put up or shut up time.

So I did something about it.  And in my last post I presented a facade class that wrapped the complexities of Roo API allowing simpler, and at least to me, more comprehend able method declarations.  My focus there was methods because I was implementing a bunch of ITD methods.  The transformation worked out well.  I was pleased with the result.

But the transformation left me questioning other code that I wrote.  Sure I did methods but what about classes?

I went back and looked at prior code. It wasn't as bad as I imagined but there were opportunities to clarify.  Principally the lesson there was; sure the methods worked out neat but what about classes and fields?  And that made me do back and redesign implementation to support the missing pieces.

Adding support for classes and fields rounds out the primal components needed for Java components.  However another aspect for manipulating these structures is the in addition to creation of elements we also need to handle modification of those complements too.

All of this of course meant and end to having one class do all.  I was stretching it before on that front and with the added functionality that was out of the question.  So the resulting code is now a collection of classes.  This in turn means handling multiple files and that in turn mean packaging.  Now I have split all this out on a separate project since I am anticipating that I will reuse this code in additional add-on's.

The source code now resides at; https://github.com/DanRepik/RooUtils.

Currently, the organization is simple there are builders for ITD's, classes, methods and fields.  All these builders extends from a parent class 'IndentifableAssetBuilder'.  Since all of these Java structures can have annotations this parent class provides common handling of that aspect.

Enjoy.

Saturday, October 26, 2013

Building the Association Add On: Modifying the Domain Model

The second part of the add-on implementation will focus on the operations to the entity classes.  Recall that in an earlier post (Association Add-on Design) we identified that the following functionality would be required.
  • A association entity between the user provided entities.
  • Annotation markup on each of the user provided entities.
  • New annotation handlers that inject entity operations to manage the association.
Here we will be focused on responding to the users command to create a new association.  This means building the functionality for the first two of these elements.

The final element, the annotation handles and the generation of the ITD's to manage the association will be covered in a subsequent post.  Here we will be concentrating on the implementation contained in the AssociationOperationsImpl class.

Before jumping into code, I have been constructing a set of wrappers in another post, 'More On the Simplifying Development Of Addons'. that simplify defining the construction of the Java software elements. Please see that for help with the expressions.

The first method introduced to this class and main entry point for the shell is the newAssociation method.  This method is required by the AssociationOperation interface.  The method parameters represent the two JavaTypes that are being associated.

    public void newAssociation(JavaType entity1, JavaType entity2 ) {
     
        // Use Roo's Assert type for null checks
        Validate.notNull(entity1, "Java type required");
        Validate.notNull(entity2, "Java type required");

        // new association entity is concatenation based on order
     JavaType entityType = getAssociationEntityType(entity1, entity2);

        buildAssociationEntity(entityType, entity1, entity2 ) ;
        addEntityAnnotation( entity1, entity2 ) ;
        addEntityAnnotation( entity2, entity1 ) ;
        
        webAssociationOperations.newAssociation( entity1, entity2 ) ;
    }


This code is pretty clean in expressing the implementation provided.  It is reliant on three private method implementations that will need to be provided.

Get Association Entity

Recall from the design discussion we need a canonical association entity name.  These entities determine if there is a relationship between the independent entities.  And throughout the course of the design the treatment of the association entities is symmetrical.  So the association of entities A to B is the same as B to A, It is important that the association entity table is the same in either case.

This method returns the canonical name of the association entity table.  Since these names will always be a concatenation between the independent entity names we merely order those to provide the canonical nature required.

 

private JavaType getAssociationEntityType(JavaType target1, JavaType target2) {
     if ( target1.getSimpleTypeName().compareTo( target2.getSimpleTypeName()) < 0 ) {
          return new JavaType( target1.getFullyQualifiedTypeName() + target2.getSimpleTypeName()) ;
     }
     return new JavaType( target2.getFullyQualifiedTypeName() + target1.getSimpleTypeName()) ;
 }


buildAssociationEntity

With the ability to create canonical association entity names we can proceed with implementing the buildAssociationEntity.  The task of this method is to build if needed an JPA entity with the independent entities as attributes.

With Roo the add on code will be run multiple times, whenever upstream dependencies change.  The Roo shell supports scripting, an I have in the past ran the same script over and over will developing it.  So the implementation code should be defensive since the asset being built may already exist.

There are four main parts to this method;
  • Attempt to obtain the ClassOrInterfaceTypeDetails for the association entity.  To do this first we need to construct a metadataId and then attempt to get it from the type location service.
  • Construct a ClassBuilder, we provide both the metadataId and our potentially null type details object.  The constructor here will use the type details if available.  
  • Declare the annotations and attribute fields.  The ClassBuilder handles the mechanics of updating the class structure.
  • And finally we pass back the results of class builder to the TypeManagementService to handle committing the changes to the project files.
And here is the implementation;


    

    private void buildAssociationEntity( JavaType entityType, JavaType target1, JavaType target2 ) {

        final String metadataId = PhysicalTypeIdentifier
                .createIdentifier(entityType, projectOperations
                        .getPathResolver().getFocusedPath(Path.SRC_MAIN_JAVA));

        // Obtain ClassOrInterfaceTypeDetails for this java type
        ClassOrInterfaceTypeDetails entityDetail = typeLocationService.getTypeDetails(entityType);

        String identifierColumn = target1.getSimpleTypeName().toUpperCase() 
          + "_" + target2.getSimpleTypeName().toUpperCase() + "_ID" ; 

        ClassBuilder classBuilder = new ClassBuilder( metadataId, entityDetail )
         .type( PhysicalTypeCategory.CLASS )
         .modifier( Modifier.PUBLIC | Modifier.FINAL )
         .named( entityType ) 
         .annotation( "org.springframework.roo.addon.javabean.RooJavaBean" )
         .annotation(new AnnotationBuilder( 
            "org.springframework.roo.addon.jpa.activerecord.RooJpaActiveRecord")
          .attribute( "identifierColumn", identifierColumn ))
         .annotation( "org.springframework.roo.addon.tostring.RooToString") 
         .field( getEntityAssociationField( metadataId, target1)) 
         .field( getEntityAssociationField( metadataId, target2)) ;
        
        typeManagementService.createOrUpdateTypeOnDisk(classBuilder.build());
    }



getEntityAssociationField


The last part of the association entity construction is to add the fields to the type.  For association entities there are two attribute (field) references.  A reference is created for each of the entities being associated, so this method is called twice.

For each entity we need to add a field reference attribute to the entity association class to both ends of the association.  Here the basic logic is first find or create a the reference field and then add the JPA annotations to the field.

 

 private FieldBuilder getEntityAssociationField( 
   String metadataId, JavaType entityType ) {

        ClassOrInterfaceTypeDetails entityDetails = typeLocationService.getTypeDetails(entityType);
        AnnotationMetadata annotation = entityDetails.getAnnotation( 
          new JavaType( "org.springframework.roo.addon.jpa.activerecord.RooJpaActiveRecord" )) ;
        if ( annotation == null ) 
         return null ;
        
        String identifierColumn = (String) annotation.getAttribute( "identifierColumn").getValue();
        if ( identifierColumn == null ) {
         return null ;
        }

  return new FieldBuilder( metadataId )
   .named(StringUtils.uncapitalize( entityType.getSimpleTypeName())) 
   .modifier( 0 )
   .type( entityType )
   .annotation("javax.persistence.ManyToOne")
   .annotation( new AnnotationBuilder( "javax.persistence.JoinColumn" )
     .attribute( "name", identifierColumn )) ;
 }



At this stage we have finished construction of the association entity.  This entity allows a many to many mapping between two independent entities.

addEntityAnnotation


Next we need to modify the independent entities that are being related together.  Here we need to inject into the independent entities the association annotation. The association annotation identifies the other independent entities that this entity has been associated with.  Recall during the design phase we recognized that an independent entity can have associations with multiple entities.  This means that the value for the annotation will be a set of entity classes, but with Java annotations we need to provide a list.

To construct this set we will need to get the current annotation, if one exists, from the details object.  If there is an existing annotation then exact the set of existing entities the class is associated with and remove that annotation.  Next add the new entity class being associated with to the set of associated classes. And finally add (or re-add) the association annotation to the domain entity.


    

private void addEntityAnnotation( JavaType entityType, JavaType with ) {
        
        // Obtain ClassOrInterfaceTypeDetails for this java type
        ClassOrInterfaceTypeDetails entityDetails = typeLocationService.getTypeDetails(entityType);

        if ( entityDetails != null ) {
        
            // assemble the set of associated entities
            Set<ClassAttributeValue> values = new HashSet<ClassAttributeValue>() ;

            AnnotationMetadata associationMetadata = MemberFindingUtils.getAnnotationOfType(entityDetails.getAnnotations(), rooAssociationType) ;
            if ( associationMetadata != null ) {
          AnnotationAttributeValue<List<ClassAttributeValue>> attributeValue = associationMetadata.getAttribute( "value" );
             values.addAll(attributeValue.getValue()) ;
         }         
            values.add( new ClassAttributeValue( new JavaSymbolName( "value" ), with )) ;

         ClassBuilder builder = new ClassBuilder( entityDetails )
          .annotation( new AnnotationBuilder( rooAssociationType )
           .attribute( "value", new ArrayList<ClassAttributeValue>( values ))) ;

         // Save changes to disk
            typeManagementService.createOrUpdateTypeOnDisk(builder.build());
        }
    }


In this method we see again the logic of;

  • Obtaining the type details from the TypeLocationService,
  • Wrapping the type details in a ClassBuilder facade object,
  • Modifying the builder,
  • And finally sending the updated class to the TypeManagementService.

This wraps things up for the implementation of the domain model handling for the association plug in.  Roo web applications follow the basic model view controller architecture.  Add on constructed in this post provides the association functionality to the model component.  In the next post we will look at the implementation for the controller portion of the architecture.