Archive for January, 2011

Implementing Modular Web Design: Part 1 – Why?

January 28, 2011

Having read Web Anatomy: Interaction Design Frameworks that Work by Robert Hoekman Jr. and Jared Spool and Modular Web Design by Nathan Curtis, I was super excited about the prospect of creating a component library for the developers here at Lampo. What’s so cool about component libraries? Let me tell you.

Imagine never having to hand-code a contact form ever again. Now I hear you, you’re saying “Kevin, I’m an awesome developer, I don’t hand-code contact forms, I’ve got code snippets, templates, and frameworks that allow me to quickly implement contact forms, why would I want a component library?” The problem with snippets, templates, and frameworks are three words that make every developer cringe: “copy and paste.”

Imagine working on a site that has 20+ contact forms all for different business modules within the company. Now imagine that you need to change something about all 20 of those forms. Now you’re saying, “But Kevin, CSS rocks my socks off, I reuse stylesheets like a champ!” To which I say, what if you need to alter the markup? What if you need to attach a bit of javascript to transform your contact forms for mobile devices? With copy and paste there’s just no global hook at the component level.

Another argument is for existing component libraries. Most of these are javascript based: jQuery UI, YUI, LivePipe etc. They’re great, but there’s still a good deal of configuration involved. You need to write the markup, create the js bindings between markup and the library, and then download a theme or write some CSS to make it all look pretty. The type of component library I’m talking about does all these things for you.

One line of code gets you markup, JS, and CSS. All wired up to work beautifully together and provide you with usability-tested, consistent, semantically-correct components to use throughout your web app. Plus you have the control to change and upgrade components on the fly and all users of your components will receive the updates. No need to do a search and replace (AKA search and destroy). It just happens.

Have I sold you yet? Do you want to build one of these? Does it sound as amazing as a triple rainbow unicorn?

Well it did to me. So how do you implement something like this? Hoekman and Spool’s book provided me with some great theory, but nothing code based. Curtis’s book does an awesome job of describing implementation for a design department (another benefit, another post), but also left me hanging when it came to coding.

So that’s where we begin. In the next post I’ll discuss how we approached the problem of actually implementing the Lampo component library lovingly known as “Gutenberg UX.”

That’s the origin story for our component library.  Have you implemented something similar or experienced any drawbacks implementing jQuery UI or another javascript component library?  Comment on this post and share your story with us!

Advertisements

Grails and Rabbits

January 12, 2011

Tim: There he is!
King Arthur: Where?
Tim: There!
King Arthur: What? Behind the rabbit?
Tim: It *is* the rabbit!
-Monty Python and the Holy Grail

This. Is. Ridiculous.

After SpringOne I was anxious to try Grails with RabbitMQ on my own.  I downloaded the complete bundle for Windows and set it up.  I’ve never run an Erlang application so I felt a bit funny, but it was simple and painless.  I set an environment variable for Erlang (ERLANG_HOME).  Then I just hard coded a ‘base’ directory for logging and whatnot in Rabbit (server.bat).  Yeah, I could have set another env var there too, but I was too anxious.

I started the server.bat file and had RabbitMQ running.  Though it was lonely.

Sir Bedevere: Well, now, uh, Lancelot, Galahad, and I, wait until nightfall, and then leap out of the rabbit, taking the French by surprise – not only by surprise, but totally unarmed!
-Monty Python and the Holy Grail

I jumped into STS and ran ‘install-plugin rabbitmq’
A simple config setting (Config.groovy):

rabbitmq {
   connectionfactory {
      username = 'guest'
      password = 'guest'
      hostname = 'localhost'
      consumers = 5
   }
   queues = {
      jimski()
   }
}

My Controller only needed to call:

rabbitSend 'jimski', msg

…and for fun I setup a Service to pull messages off the queue:

static rabbitQueue = "jimski"
void handleMessage(msg) {
   println "received message: $msg"
}

Voila! Messages taken in by the Controller make a call to rabbitSend and magically the Service sees them and pulls them out to display.  Crazy easy.  Crazy cool.

I’m going to keep at it.  Let me know your experiences with queuing.

Add Spring Security to ColdFusion

January 10, 2011

We are evaluating Spring Security as a part of our authentication and authorization platform. Since we have many ColdFusion apps, it was natural for us to see how it would work in tandem with ColdFusion. Fortunately, since ColdFusion is a Java web application, Spring Security fits right in.

In this post, I’ll show the basics of connecting Spring Security with ColdFusion. I’m not intending to teach how Spring Security works or other details of implementation. For more information, see the Spring Security Reference Documentation (also available as a PDF).

At a high level, you add Spring Security as a Servlet Filter that is setup to run before the ColdFusion servlet in the Java web application config file (web.xml). To make it as easy as possible to see how it works, I’ll show you how to to setup the Spring Security tutorial app. I’m starting with a new install of ColdFusion 9.0.1, installed as a J2EE app under Tomcat 6.0.29 (running on JDK 1.6.0.22, 64-bit on Windows XP Pro).

  1. Download Spring Security from here (using version 3.0.5, the latest as of this writing).
  2. Extract the zip file (spring-security-3.0.5.RELEASE.zip).
  3. Extract the tutorial WAR file located in
    spring-security-3.0.5.RELEASE/dist/spring-security-samples-tutorial-3.0.5.RELEASE.war
    to a local directory (I’ll call it <tutorial-war>).NOTE: If you’ve never run the Spring Security tutorial, you can just put the <tutorial-war> directory into the /webapps directory of your Tomcat app server and run it. Here is more info about Spring Security tutorial.
  4. Copy all of the .jar files from:
    <tutorial-war>/WEB-INF/lib
    into:
    <cf-app>/WEB-INF/lib
  5. Copy the file:
    <tutorial-war>/WEB-INF/classes/log4j.properties
    to:
    <cf-app>/WEB-INF/classes/log4j.properties
  6. Copy the file:
    <tutorial-war>/WEB-INF/applicationContext-security.xml
    to:
    <cf-app>/WEB-INF/applicationContext-security.xml
  7. Copy indicated lines from:
    <tutorial-war>/WEB-INF/web.xml
    to:
    <cf-app>/WEB-INF/web.xml 

    1. Under the line:
      <description>Adobe ColdFusion 9</description>
      (line 5 in my stock CF9 web.xml), insert the <context-param /> blocks from
      <tutorial-war>/WEB-INF/web.xml
      (NOTE: In the code below, I removed the first line in the first <context-param /> from the tutorial that said
      classpath:applicationContext-business.xml.):

      	<!-- INSERTED FOR SPRING SECURITY -->
      
          <!--
            - Location of the XML file that defines the root application context
            - Applied by ContextLoaderListener.
            -->
          <context-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>
      			<!-- REMOVED classpath:applicationContext-business.xml -->
                  /WEB-INF/applicationContext-security.xml
              </param-value>
          </context-param>
      
          <context-param>
              <param-name>log4jConfigLocation</param-name>
              <param-value>/WEB-INF/classes/log4j.properties</param-value>
          </context-param>
      
          <context-param>
              <param-name>webAppRootKey</param-name>
              <param-value>tutorial.root</param-value>
          </context-param>
      
      	<!-- END INSERT FOR SPRING SECURITY -->
      
    2. Under the many <context-param /> blocks and before the <filter /> blocks (around line 64 in my stock CF9 web.xml), insert:
      	<!-- INSERTED FOR SPRING SECURITY -->
      
          <filter>
              <filter-name>springSecurityFilterChain</filter-name>
              <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
          </filter>
      
          <filter-mapping>
            <filter-name>springSecurityFilterChain</filter-name>
            <url-pattern>/*</url-pattern>
          </filter-mapping>
      
      	<!-- END INSERT FOR SPRING SECURITY -->
      
    3. Under the <filter-mapping /> blocks and before the <listener /> blocks (around line 167 in my stock CF9 web.xml), insert:
      	<!-- INSERTED FOR SPRING SECURITY -->
      
          <listener>
              <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
          </listener>
      
          <listener>
            <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
          </listener>
      
          <listener>
              <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
          </listener>
      
      	<!-- END INSERT FOR SPRING SECURITY -->
      
  8. Now, we have to adjust ColdFusion’s logging configuration so that Spring Security’s configuration and libraries are favored.
    1. Rename the file:
      <cfapp>/WEB-INF/cfusion/lib/commons-logging-1.1.1.jar
      to:
      <cfapp>/WEB-INF/cfusion/lib/commons-logging-1.1.1.jar.bak
    2. Rename the file:
      <cfapp>/WEB-INF/cfusion/lib/commons-logging-api-1.1.1.jar
      to:
      <cfapp>/WEB-INF/cfusion/lib/commons-logging-api-1.1.1.jar.bak
    3. Rename the file:
      <cfapp>/WEB-INF/cfform/jars/commons-logging.jar
      to:
      <cfapp>/WEB-INF/cfform/jars/commons-logging.jar.bak
    4. Rename the file:
      <cfapp>/WEB-INF/cfform/jars/commons-logging.properties
      to:
      <cfapp>/WEB-INF/cfform/jars/commons-logging.properties.bak
    5. Create the file:
      <cfapp>/WEB-INF/classes/commons-logging.properties
      , and insert the following into it:

      	org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.SLF4JLogFactory
      	org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
      
  9. Extract the file security.tld from the META-INF directory of the file
    <cfapp>/WEB-INF/lib/spring-security-taglibs-3.0.5.RELEASE.jar
    and put it into the
    <cfapp>/WEB-INF/lib
  10. Edit the file:
    <cf-app>/WEB-INF/applicationContext-security.xml
    and comment out the <session-management /> block (around line 35), like so:

    	<!--
    	<session-management invalid-session-url="/timeout.jsp">
    		<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
    	</session-management>
    	-->
    
  11. That should be all of the server-side configuration you need to make Spring Security work with ColdFusion. When you startup your app server, you should see a lot of Spring Security related output in your console, ending with:

    Root WebApplicationContext: initialization completed in  ms

    Since you can use JSP Tag Libraries in ColdFusion templates or CFCs, you can import Spring Security’s taglib and then easily restrict access to certain content or code using Spring Security’s access expressions. Here’s an example CFM file.

    <cfimport taglib="/WEB-INF/lib/security.tld" prefix="security">
    <html>
    <head>
    	<title>Spring Security on ColdFusion tester</title>
    </head>
    <body>
    	<h1>Spring Security on ColdFusion Test Application</h1>
    	<cfinclude template="/include/nav.cfm" />
    
    	<security:authorize access="isAuthenticated()">
    	<p>You can see this because you are authenticated.</p>
    	</security:authorize>
    
    	<security:authorize access="hasRole('ROLE_SUPERVISOR')">
    	<p>You can see this because you have supervisor permission.</p>
    	</security:authorize>
    
    </body>
    </html>
    

    That’s just the beginning — but a pretty strong beginning that opens up a whole new world of enterprise-class security.