Okay, it is still a work in progress, . . . But, I have pushed the Griffon Collab Todo application to Github (http://github.com/jshingler/gcollabtodo/wikis). Griffon Collab Todo is a reimplementation of the Swing Client found in Chapter 13 of Beginning Groovy and Grails using Griffon.
The application is a Griffon (Groovy & Swing) client to a Grails Web Application. It communicates with the Grails application using a JSON Restful approach.
While it is still a work in progress, . . . It does give you an idea of they types of things you can do with Griffon.
Stay tuned, as time permits, I will blog more info on my experiences with Griffon. BTW, it has been fun.
Danno, Andres, and James have done a Great Job with Griffon!
Thursday, November 27, 2008
Griffon Collab Todo Example
Monday, November 24, 2008
Installing Griffon Snapshot
Griffon is to Desktop as Grails is to Web Apps.
Here are some instructions for installing the latest Griffon Dev Snapshot on Windows.
Assumptions: java is already installed.
1. Download the source (http://svn.codehaus.org/griffon) using your favorite Subversion tool. I like SmartSVN (http://www.syntevo.com/smartsvn)
2. cd download\core\trunk
3. run ant to build the code
4. create an installer. ant create-installer-izpack (look in ant\build\installer.xml for other options)
5. execute trunk\dist\griffon-installer-0.1.SNAPSHOT.jar (java -jar griffon-installer-0.1.SNAPSHOT.jar)
NOTE: Depending upon when you download the source, there is an error in the windows installer. It puts a PATH entry in the User variables that contains ${OLD_PATH_VALUE}. This creates a problem. A work around is to delete the PATH entry in User Variables and add the appropriate info to the System PATH variable. You should also make sure that GRIFFON_HOME has been defined.
Sunday, November 2, 2008
Griffon Collab-Todo
Coming Soon! In Chapter 13 of "Beginning Groovy and Grails" I built a Swing GUI using SwingXBuilder that interacted with a Grails RESTFul Web Service. I am finishing the process of creating a Griffon version of the same application. It is starting to look good.
I will be uploading the source to the Beginning Groovy and Grails website in the near future. Stay tuned.
Thursday, October 23, 2008
Aug 12 COJUG - Groovy / Grails Presentation
Groovy and Grails have given us the ability to leverage the strength of the Java Platform (and Eco System) and the productivity of "Convention over Configuration" to construct websites. But what if the User Interface requirements of your new application is best solved with the type of interaction a desktop application provides?
Groovy brings the same productivity gain to desktop applications that Grails brings to web applications. This session will use the Groovy SwingBuilder and popular open source libraries to build a desktop application to interact with a Grails backend.
Here is the link to the Groovy and Grails presentation I did on August 12, 2008.
COJUG 8/12 Groovy / Grails Presentation
Tuesday, August 5, 2008
BGG - Apress book of the day
HURRY, Beginning Groovy and Grails is the Apress book of the day, you can get the PDF at a reduced price.
http://www.apress.com/info/dailydeal
Thursday, July 3, 2008
Phone Number Custom Constraint for Grails
Grails contains really great Validators that you can use in your constraints. But it is missing one that I need for a project I am working on, . . . There is no PhoneNumber constraint. Luckily, I ran across Geoff Lane's Post: Build a Custom Validator in Grails with a Plugin
In Chapter 2 Regular Expressions section of Beginning Groovy and Grails, we show using a regular expression to validate phone numbers. Well, now I had all of the parts required to make a PhoneNumber Custom Validator.
Usage:
class party {
String name
String workPhone
static constraints = = {
workPhone(phoneNumber:true)
}
The Constraint:
import org.codehaus.groovy.grails.validation.AbstractConstraint
import org.springframework.validation.Errors
/**
* Phone Number Constraint
*
* The phone number constraint is used to validate phone number formats
*
* Registering the Constraint.
*
* App Registration Config.groovy
*
* org.codehaus.groovy.grails.validation.ConstrainedProperty.registerNewConstraint(
* PhoneNumberConstraint.NAME, PhoneNumberConstraint.class)
*
*
* Plugin Registration MyPlugin.groovy:
*
* def doWithSpring = {
* ConstrainedProperty.registerNewConstraint(PhoneNumberConstraint.NAME, PhoneNumberConstraint.class);
* }
*
*
* This plugin is based upon the following posts:
*
* http://www.zorched.net/2008/01/25/build-a-custom-validator-in-grails-with-a-plugin/
* http://www.zorched.net/2008/01/26/custom-validators-in-grails-in-a-single-app/
*
* @author Jim Shingler ShinglerJim at gmail.com
*/
class PhoneNumberConstraint extends AbstractConstraint {
private static final String DEFAULT_MESSAGE_CODE = "default.phoneNumber.invalid.message";
public static final String NAME = "phoneNumber";
private boolean validateConstraint
public void setParameter(Object constraintParameter) {
if (!(constraintParameter instanceof Boolean))
throw new IllegalArgumentException("Parameter for constraint ["
+ NAME + "] of property ["
+ constraintPropertyName + "] of class ["
+ constraintOwningClass + "] must be a boolean value");
this.validateConstraint = ((Boolean) constraintParameter).booleanValue()
super.setParameter(constraintParameter);
}
protected void processValidate(Object target, Object propertyValue, Errors errors) {
if (validateConstraint && !validate(target, propertyValue)) {
def args = (Object[]) [constraintPropertyName, constraintOwningClass,
propertyValue]
super.rejectValue(target, errors, DEFAULT_MESSAGE_CODE,
"not." + NAME, args);
}
}
boolean supports(Class type) {
return type != null && String.class.isAssignableFrom(type);
}
String getName() {
return NAME;
}
/**
* This is where the real work is. Use a regular expression to validate
* the phone number.
*
* The core logic of the constraint is implemented as its own method to make the
* constraint easier to test.
*/
boolean validate(target, propertyValue) {
propertyValue ==~ /^[01]?\s*[\(\.-]?(\d{3})[\)\.-]?\s*(\d{3})[\.-](\d{4})$/
}
}
The real work is in the validate function.
As you can see, creating a custom constraint is really pretty easy. Just make sure that you follow the directions in the constraint class comments to register the constraint.
Friday, June 13, 2008
BGG – Beginning Groovy and Grails – June 23
BGG is imminent. It is scheduled for release on June 23.
Here is a brief overview of the books structure.
Chapter 1 - Introduction to Groovy
This chapter defines Groovy, explains hot to install it, and then through example, demonstrates its power, flexibility, and readability compared to the Java language
Chapter 2 – Groovy Basics
This chapter explains the basic Groovy syntax, structures, and tools
Chapter 3 – More Advanced Groovy
This chapter goes beyond the Groovy basics to cover unit testing, XML processing, templating, and metaprograming. In includes a discussion on domain-specific languages (DSL).
Chapter 4 – Introduction to Grails
This chapter defines the Grails architecture and its features. It then explains how to install Grails and get started developing applications with scaffolding.
Chapter 5 – Building the User Interface
This chapter explains how to combine Groovy Server Pages (GSP), controllers, Grails tags, templates, and Cascading Style Sheets (CSS) to build a basic user interface.
Chapter 6 – Building Domains and Services
This chapter explains how Grails uses a domain-driven approach to developing applications and how domain objects can be persisted using the powerful Grails Object Relational Mapping (GORM) framework. The chapter concludes by showing how you organize application logic into reusable and injectable services.
Chapter 7 – Security in Grails
This chapter explains and demonstrates the alternative security options available in Grails.
Chapter 8 – Web 2.0 – Ajax and Friends
This chapter explains how to add usability to your application through adding Ajax functionality, searching, and RSS.
Chapter 9 – Web Services
This chapter shows how to expose parts of your application to other clients using representational state transfer (REST) web services.
Chapter 10 – Reporting
This chapter explains how to use JasperReports and iReports to expose reports in multiple formats, including PDF, HTML, XML, and XLS.
Chapter 11 – Batch Processing
This chapter showcases how to schedule jobs to run automatically and how to generate e-mail messages.
Chapter 12 – Deploying and Upgrading
This chapter describes how to configure, package, and deploy Grails applications to alternative database and application servers.
Chapter 13 – Alternative Clients
This chapter builds a Swing client using Groovy that interacts with the Grails application through the RESTful web services built in Chapter 9
You can order your copy from Amazon, Beginning Groovy and Grails
Wednesday, May 21, 2008
Beginning Groovy and Grails - New Book
You want to learn Groovy and Grails and don’t know where to start. The wait is almost over and your journey is about to begin. Beginning Groovy and Grails (BGG) is an ideal primer for learning Groovy and Grails.
BGG will take you from installation of Groovy and Grails all the way to developing a Collaborative Todo web application and a Groovy Swing user interface. Along the way, you will learn how to uses Web 2.0 and AJAX with Grails. You will explore 3 different security plugins. You will learn how use Jasper Reports and Quartz Plugin. You will develop RESTful web services. By the time you have completed your journey you will have a solid understanding of Groovy and Grails. You will be ready to start you’re your next assignment using Groovy and Grails.
Stay tuned to this Blog, . . . more information is coming. You can pre-order your copy of Beginning Groovy and Grails from Amazon.
Thursday, May 15, 2008
ACORD Enterprise Architecture - Round Table
I had the pleasure of participating on the ACORD / LOMA Forum Enterprise Architecture Best Practices round table. It was great. We had a good round table panel and the audience asked some very thought full questions. The time just flew by.
I would like to thank all of Round Table participants, Frank Neugebauer and ACORD for putting the round table together. I look forward to working with you on the Information Model Advisory committee.
Enterprise Architecture Best Practices
Presenter(s): Gwen Smith, AXIS Capital; Salvador Sierra, AXIS Insurance; William Duym, AIG; Rich Maynard, The Hartford; Jim Shingler, Nationwide; Frank Neugebauer, ACORD
This panel of enterprise architects will discuss their experiences with using disciplined best practices to create well-defined enterprise architectures that meet business needs. Learn from their collective experiences, but will start with a base discussion of The Open Group Architecture Framework, including how ACORD Standards (including the ACORD Standards Framework) fit.
Sunday, March 30, 2008
Holy Grail of 3 Column Layout
While Grails really makes the MVC portion of web development easier, Cascading Style Sheets (CSS) is still really tough. I wanted a 3 Column layout with a header and footer created using CSS. This sounds easy enough, but it was more difficult than you would think. Especially if you want it to work with multiple browsers.
I spent several hours working on it, more than I would like to admit. Then I ran across Matthew James Talyor's work on 3 column liquid layouts. Matthew did a really nice job and it works exactly as you would expect. So I tried to weave it into a site I was creating. I was using Firefox and everything was going great until I tried to bring it up in Explorer. Ooops!
To make a long store short, I went back to the beginning and scrapped all my pre-existing CSS and started from Matthews. That did the trick. It rendered correctly in Firefox and Explorer both.
I was so happy figured I would probably use this layout again. So, I created a generic Grails application preconfigured to use the 3 column layout. As you would expect, all of the real work is in main.gsp and a new css file I created css file holygrail.css.
So in the spirit of hoping to make someone else's life a little easier, here are the main.gsp and holygrail.css files.
main.gsp
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title><g:layoutTitle default="www.Grails.org"/></title>
<link rel="stylesheet" href="${createLinkTo(dir: 'css',
file: 'holygrail.css')}"/>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8"/>
<meta name="description" content="The Holy Grail 3 column Liquid Layout. Pixel widths. Cross-Browser. Equal Height Columns."/>
<meta name="keywords" content="The Holy Grail 3 column Liquid Layout. Pixel widths. Cross-Browser. Equal Height Columns."/>
<meta name="robots" content="index, follow"/>
<link rel="shortcut icon" href="${createLinkTo(dir: 'images', file: 'favicon.ico')}" type="image/x-icon"/>
<g:layoutHead/>
</head>
<body>
<!--
This is a Grails example of the Holy Grail 3 column Liquid Layout work by Mathew Taylor.
For more information, please see his original work at:
http://matthewjamestaylor.com/blog/ultimate-3-column-holy-grail-pixels.htm
-->
<div id="header">
<!-- Header start -->
<g:render template="/common/header"/>
<!-- Header end -->
</div>
<div class="colmask holygrail">
<div class="colmid">
<div class="colleft">
<div class="col1wrap">
<div class="col1">
<!-- Column 1 start -->
<g:layoutBody/>
<!-- Column 1 end -->
</div>
</div>
<div class="col2">
<!-- Column 2 start -->
<g:render template="/common/leftbar"/>
<!-- Column 2 end -->
</div>
<div class="col3">
<!-- Column 3 start -->
<g:render template="/common/rightbar"/>
<!-- Column 3 end -->
</div>
</div>
</div>
</div>
<div id="footer">
<!-- Footer start -->
<g:render template="/common/footer"/>
<!-- Footer end -->
</div>
</body>
</html>
holygrail.css
/* General styles */
body {
margin:0;
padding:0;
border:0; /* This removes the border around the viewport in old versions of IE */
width:100%;
background:#fff;
min-width:600px; /* Minimum width of layout - remove line if not required */
/* The min-width property does not work in old versions of Internet Explorer */
font-size:90%;
}
a {
color:#369;
}
a:hover {
color:#fff;
background:#369;
text-decoration:none;
}
h1, h2, h3 {
margin:.8em 0 .2em 0;
padding:0;
}
p {
margin:.4em 0 .8em 0;
padding:0;
}
img {
margin:10px 0 5px;
}
/* Header styles */
#header {
clear:both;
float:left;
width:100%;
}
#header {
border-bottom:1px solid #000;
}
#header p,
#header h1,
#header h2 {
padding:.4em 15px 0 15px;
margin:0;
}
#header ul {
clear:left;
float:left;
width:100%;
list-style:none;
margin:10px 0 0 0;
padding:0;
}
#header ul li {
display:inline;
list-style:none;
margin:0;
padding:0;
}
#header ul li a {
display:block;
float:left;
margin:0 0 0 1px;
padding:3px 10px;
text-align:center;
background:#eee;
color:#000;
text-decoration:none;
position:relative;
left:15px;
line-height:1.3em;
}
#header ul li a:hover {
background:#369;
color:#fff;
}
#header ul li a.active,
#header ul li a.active:hover {
color:#fff;
background:#000;
font-weight:bold;
}
#header ul li a span {
display:block;
}
/* 'widths' sub menu */
#layoutdims {
clear:both;
background:#eee;
border-top:4px solid #000;
margin:0;
padding:6px 15px !important;
text-align:right;
}
/* column container */
.colmask {
position:relative; /* This fixes the IE7 overflow hidden bug and stops the layout jumping out of place */
clear:both;
float:left;
width:100%; /* width of whole page */
overflow:hidden; /* This chops off any overhanging divs */
}
/* holy grail 3 column settings */
.holygrail {
background:#ff9; /* Right column background colour */
}
.holygrail .colmid {
float:left;
width:200%;
margin-left:-200px; /* Width of right column */
position:relative;
right:100%;
background:#fff; /* Centre column background colour */
}
.holygrail .colleft {
float:left;
width:100%;
margin-left:-50%;
position:relative;
left:400px; /* Left column width + right column width */
background:#FFD8B7; /* Left column background colour */
}
.holygrail .col1wrap {
float:left;
width:50%;
position:relative;
right:200px; /* Width of left column */
padding-bottom:1em; /* Centre column bottom padding. Leave it out if it's zero */
}
.holygrail .col1 {
margin:0 215px; /* Centre column side padding:
Left padding = left column width + centre column left padding width
Right padding = right column width + centre column right padding width */
position:relative;
left:200%;
overflow:hidden;
}
.holygrail .col2 {
float:left;
float:right; /* This overrides the float:left above */
width:170px; /* Width of left column content (left column width minus left and right padding) */
position:relative;
right:15px; /* Width of the left-had side padding on the left column */
}
.holygrail .col3 {
float:left;
float:right; /* This overrides the float:left above */
width:170px; /* Width of right column content (right column width minus left and right padding) */
margin-right:45px; /* Width of right column right-hand padding + left column left and right padding */
position:relative;
left:50%;
}
/* Footer styles */
#footer {
clear:both;
float:left;
width:100%;
text-align: center;
border-top:1px solid #000;
}
#footer p {
padding:10px;
margin:0;
}
Friday, March 21, 2008
Grails Filters, Form Submission workaround - Revisited
Good News! Grails 1.0.2 resolves the Filters, Form Submission problem.
I downloaded Grails 1.0.2 and retested with the application below. The workaround is no longer needed. Filters work as expected when submitting an edit, update, or delete request from a form.
Big Thanks to the Grails Team.
Wednesday, March 19, 2008
Grails Filters, Form Submission workaround
Grails Filters are very cool. Much better than action interceptors in my opinion. So much better that I will be surprised if I write another action interceptors.
There is just one small hiccup in the current version of Grails (1.0.1).
Lets say you create a User object and have your standard CRUD actions on it. What if you want to make sure that the only person allowed to update the user record is the actual user. You would neet to put guard logic on the UserController's Edit, Update, and Delete actions. You could do that or create a filter.
Give it a try using the filter below.
class UserFilters {
def filters =
userModificationCheck(controller:'user', action:'*') {
before = {
def currActionName = (actionName == null ? 'index' : actionName)
println "=================> BEFORE: The actionName is now ${currActionName}"
}
after = {
def currActionName = (actionName == null ? 'index' : actionName)
println "=================> AFTER: The actionName is now ${currActionName}"
}
}
}
}
This is a simple filter that prints the action name. After all you only want to do this for edit, update, and delete actions. So you want to make sure you can get the action names.
What you will find is that you use use a fully pathed URL such as http://localhost:8080/myApp/user/edit/1, everything works fine. But if you go to the User Listing > Select a User > and press the form's Edit button, . . . Ooops the action in the before filter doesn't say edit, is says index.
Probably not what you expected, I know I didn't. There is a bug in Grails 1.01, it is scheduled to be fixed in 1.0.2.
Luckly, there is a simple work around for this problem. In the filter, try printing out the params. You will discover a _action_**** entry in the params. Grails uses the entry to determine which action to call on the controller.
Try replacing the currActionName line with the following:
def currActionName = actionName ?: params.find {it.key ==~ "_action_.*"}?.value?.toLowerCase()
It uses a regular expression to find a key beginning with _action_ and graps the value.
This little work around should get you going again.
Monday, March 3, 2008
Grails Podcast is BACK!
The Grails Podcast is BACK!
Glen Smith (Groovy Blogs, Gravel), has joined Seven as a cohost on the Grails Podcast.
In the latest podcast, Seven and Glen bring us upto speed on the latest Groovy and Grails, and the G2X conference.
Saturday, March 1, 2008
Groovy Closures and Java Methods
Steven Devijver has posted a couple of VERY good articles on Groovy DZone about Groovy Closures and Java Methods. I highly recommend these articles.
Higher Order functions with Groovy, part 1, part 2, part 3
They do a good job of explaining all of the ins and outs of closures and methods in Groovy.
Tuesday, February 26, 2008
FallME 0.6 Released
FallME (https://fallme.dev.java.net) 0.6 has been released.
FallME functionality was enhance to make configuration of Form injection easier.
This release include a simple sample application that demonstrates using FallME. We hope to have additional examples and documentation available shortly. In the meantime, . . . you can start to get a feel for FallME by looking at the sample application.
- Start by looking at the PreferencesBeanConfigs.java. It shows how to configure the IOC.
- Take a look at the PreferencesMobile.java (Midlet). It shows how to bootstrap the application container.
- Finally, look at MainFormBuilder.java. When the Midlet asks the BeanFactory for the MainForm, the BeanFactory uses the MainFormBuilder to construct the Form.
Wednesday, January 30, 2008
FallME Released
I am proud to announce a new open source project for the Java mobile and embedded community. Chris Judd and myself have released the first version of FallME version 0.5. FallME is a Java ME framework based on the popular Spring Framework but designed for mobile devices including those running MIDP. This framework provides an IoC container as well as a RecordStoreTemplate. You can download it and find more details at https://fallme.dev.java.net/.
Friday, January 25, 2008
New Groovy Eclipse Plugin
A new version of the Groovy Eclipse plug is available (Version 1.5.1.200801232227) the update site is: http://dist.codehaus.org/groovy/distributions/update
I just installed it, it is definitely worth upgrading, it contains several new features that make the plugin more usable and closer to what you would expect (JDT). It also contains several bug fixes there were a little annoying.
A Couple of the more noticable enhancements:
- Support of java doc /*
- Code completion improvements Ctrl-space
- Quick Outline Ctrl-O
- Project Explorer shows groovy methods
(Not working in my environment)
Rod Johnson speaks at COJUG
Last night, Columbus was privileged to have Rod Johnson, the father of the Spring Framework, speak at the Central Ohio Java Users Group (COJUG).
Rod spoke about Spring 2.5 features and SpringSource's focus. It sounds like SpringSource is going to be make a strong commitment to the Web space. They are focusing on Spring Webflow, Spring MVC, and providing more support for JSF, and web frameworks.
It was a great night for the COJUG.
I look forward to seeing you all there at next months meeting.
Sunday, January 13, 2008
Groovy is a Better Java
At Code Mash, Neal Ford, Chris Judd, and I had a interesting chat about Groovy as a Better Java. The question that we came to ask : Is Groovy Java 3.0 or is it what JDK 2.0 should have been?
The one thing that we all agreed to is: Groovy is a Better Java.
What do you think?
Monday, January 7, 2008
Going to Code Mash
www.codemash.org
Hey Code Mash starts this week. I am looking forward to it. Hopefully, I'll have an opportunity to blog about some of the sessions.