Archive for the ‘Uncategorized’ Category

Customized Grails Controller for REST

November 22nd, 2011

Grails can do RESTfull easily enough, but I wanted a restful API from grails without throwing out grails scaffolding, So I decided to customize Grails’ controller template.

grails install-templates

then in [app-name]/src/templates/scaffolding/Controller.groovy

import org.springframework.dao.DataIntegrityViolationException
import grails.converters.XML
import grails.converters.JSON

class ${className}Controller {

	static allowedMethods = [list:'GET',
		show:'GET',
		edit:['GET', 'POST'],
		save:'POST',
		update:['POST','PUT'],
		delete:['POST','DELETE']
	]

	def index() {
		redirect(action: "list", params: params)
	}

	def list() {
		params.max = Math.min(params.max ? params.int('max') : 50, 200)
		def list = ${className}.list(params)
		def listObject = [${propertyName}List: list, ${propertyName}Total: ${className}.count()]
		withFormat {
			html listObject
			json { render list as JSON }
			xml { render listObject as XML }
		}
	}

	def create() {
		[${propertyName}: new ${className}(params)]
	}

	def save() {
		def ${propertyName} = new ${className}(params)
		if (!${propertyName}.save(flush: true)) {
			withFormat {
				html {render(view: "create", model: [${propertyName}: ${propertyName}])}
				json {
					response.status = 403
					render ${propertyName}.errors as JSON
				}
				xml {
					response.status =403
					render ${propertyName}.errors as XML
				}
			}
			return
		}
		flash.message = message(code: 'default.created.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), ${propertyName}.id])
		withFormat {
			html {
				redirect(action: "show", id: ${propertyName}.id)
			}
			json {
				response.status = 201
				render ${propertyName} as JSON
			}
			xml {
				response.status = 201
				render ${propertyName}.id
			}
		}
	}

	def show() {
		def ${propertyName} = ${className}.get(params.id)
		if (!${propertyName}) {
			withFormat {
				html {
					flash.message = message(code: 'default.not.found.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), params.id])
					redirect(action: "list")
				}
				json { response.sendError(404) }
				xml { response.sendError(404) }
			}
			return
		}
		def object = [${propertyName}: ${propertyName}]
		withFormat {
			html {object}
			json { render object as JSON }
			xml { render object as XML }
		}
	}

	def edit() {
		def ${propertyName} = ${className}.get(params.id)
		if (!${propertyName}) {
			flash.message = message(code: 'default.not.found.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), params.id])
			redirect(action: "list")
			return
		}
		[${propertyName}: ${propertyName}]
	}

	def update() {
		def ${propertyName} = ${className}.get(params.id)
		if (!${propertyName}) {
			withFormat {
				html {
					flash.message = message(code: 'default.not.found.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), params.id])
					redirect(action:"list")
				}
				json { response.sendError(404) }
				xml { response.sendError(404) }
			}
			return
		}

		if (params.version) {
			def version = params.version.toLong()
			if (${propertyName}.version > version) {
				${propertyName}.errors.rejectValue("version", "default.optimistic.locking.failure",
						  [message(code: '${domainClass.propertyName}.label', default: '${className}')] as Object[],
						  "Another user has updated this ${className} while you were editing")
				withFormat {
					html {render(view: "edit", model: [${propertyName}: ${propertyName}])}
					json { response.sendError(409) }
					xml { response.sendError(409) }
				}
				return
			}
		}

		${propertyName}.properties = params

		if (!${propertyName}.save(flush: true)) {
			withFormat {
				html {render(view: "edit", model: [${propertyName}: ${propertyName}])}
				json {
					response.status = 403
					render ${propertyName}.errors as JSON
				}
				xml {
					response.status = 403
					render ${propertyName}.errors as XML
				}
			}
			return
		}
		withFormat {
			html {
				flash.message = message(code: 'default.updated.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), ${propertyName}.id])
				redirect(action: "show", id: ${propertyName}.id)
			}
			json {
				response.status = 204
				render ${propertyName} as JSON
			}
			xml {
				response.status = 204
				render ''
			}
		}
	}

	def delete() {
		def ${propertyName} = ${className}.get(params.id)
		if (!${propertyName}) {
			withFormat {
				html {
					flash.message = message(code: 'default.not.found.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), params.id])
					redirect(action: "list")
				}
				json { response.sendError(404) }
				xml { response.sendError(404) }
			}
			return
		}
		try {
			${propertyName}.delete(flush: true)
			withFormat {
				html {
					flash.message = message(code: 'default.deleted.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), params.id])
					redirect(action: "list")
				}
				json {
					response.status = 204
					render ''
				}
				xml {
					response.status = 204
					render ''
				}
			}
		}
		catch (DataIntegrityViolationException e) {
			withFormat {
				html {
					flash.message = message(code: 'default.not.deleted.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), params.id])
					redirect(action: "show", id: params.id)
				}
				json { response.sendError(500) }
				xml { response.sendError(500) }
			}
		}
	}

}

then modify your UrlMappings.groovy file to look something like this:

class UrlMappings {

	static mappings = {
		"/$controller/$action?/$id?"{
			constraints {
			// apply constraints here
			}
		}
		name api0: "/api/$controller/$id"(parseRequest:true){
			action = [GET: "show", PUT: "update", DELETE: "delete"]
			constraints {
				id(matches:/\d+/)
			}
		}

		name api1: "/api/$controller"(parseRequest:true){
			action = [GET: "list", POST: "save"]
		}
	}
}

I found the JSON Restful plugin a while after I already did most of this, so that is another way to go. Other than it having some issues in grails 2 right now it looks like a really good option, but one thing I like about my approach is that if you want to customize your API in fine detail you can do so. You can always generate individual controllers and modify them of course. Another option is registering custom marshallers. The simple example for customizing your JSON output without changing any controller code would be doing something like this in your Bootstrap.groovy

import grails.converters.JSON
class BootStrap {
  def init = {servletContext ->;
    JSON.registerObjectMarshaller(Person) {
      def returnArray = [:]
      returnArray['name'] = it.name
      returnArray['addrs'] = it.addresses
      return returnArray
    }
    ...
  }

...

A Service is not a Product

October 28th, 2010

A recent article details How Google Is ‘Closed’, Just Like Apple

I have to disagree. They may both have aspects that are closed, but they are definitely not ‘just like’ each other. Apple sells a product that is closed, Google sells a service that is closed. The difference is crucial, and should be obvious to anyone who has taken business 101. Some companies make money on a product some on a service. A closed service is nothing new, and doesn’t offend me (though it may entrap me). A closed product is a new concept. It is offensive because it restricts me in new ways that I am not accustomed to evidenced by new laws that have to be created to enforce the restrictions. I would add that if these restrictions actually were justifiable we wouldn’t need new laws to enforce them and thus wouldn’t feel offended.

Apple has plenty of closed services as well by the way, so they may qualify as doubly closed, or maybe closed squared?

my sunspider test results for Sept.

September 22nd, 2010

Run on Ubuntu 10.04 64bit on core2quad@2.66Ghtz

Browser Version Sunspider result
Chromium 7.0.530.0 336.0ms +/- 9.1%
Midori 0.2.8 366.4ms +/- 2.1%
Epiphany 2.30.2 454.4ms +/- 3.8%
Opera 10.62 397.8ms +/- 2.8%
Firefox 3.6.11pre 1805.0ms +/- 3.0%
Swiftfox 3.6.10 955.0ms +/- 1.3%
Firefox 4b7pre 462.6ms +/- 7.9%

Chromium is still leading the pack, but it’s lead is not as dramatic as it used to be. Firefox 4 is shaping up to be a pretty stellar browser overall. Still waiting for the UI on Linux to get some love though. Swiftfox, which is essentially Firefox optimized for specific chip architectures, is interesting. It is almost twice as fast in this benchmark compared to standard Firefox . Maybe Firefox should do this themselves if they want to eek out some extra performance, but I suppose there are reasons not to as well.

Looking back it is pretty impressive how much faster browser javascript has gotten over the last couple years.

My Android Experience Thus Far

August 24th, 2010

I have had my Samsung Moment since around Thanksgiving 2009. It came with Adroid 1.5 initially and was my first smartphone. I played with it quite a bit at first, but after the first few months the novelty mostly wore off. I fell into a pattern of using it for its browser, email, twitter (mostly reading tweets not tweeting myself.) and occasionally for taking photos. Battery life was pretty dismal which actually discouraged me from using it because I would rather not have a dead phone by the afternoon.

Sometime in the spring it got updated to 2.1 which was sort of a let down to be honest. Most things were just as they were. There were a few more options as far as apps, and a nice new unlock screen, but that about covers it. standard 2.1 stuff was left out by Sprint. I guess they had their reasons.

About a month ago I decided I wanted to try to do some deeper customization. These phones are like little computers. If I could install Ubuntu on my laptop why couldn’t I do something similar on this phone.  Android is basically a Linux distro for mobile phones.

Anyway long story short – rooted it and installed custom ROM with the help of sdx-developers. I actually had some reasons for work that prompted this move, but those aren’t so relevant here. The phone is awesome again. A couple new features and capabilities come with root access that only geeks will appreciate, and all the bloatware that I never used and couldn’t get rid of was gone, but the most useful aspect is the dramatically improved battery life. Now a full day of heavy use is no problem. Two full days is pushing it a bit, but I do it from time to time. The wireless tethering is slick and actually useful when traveling. (did I mention I am not paying Sprint for this feature? … don’t tell….)

It comes with some consequences. The occasional random reboot or flickery screen, but so far they haven’t really interrupted anything I needed to do. reboot is faster than it used to be too. Overall the stability isn’t really a hit, because the phone wasn’t glitch free before anyway.

What is cool is that these now ‘old’ phones (Sprint tweeted they were done providing updates for the Moment 6-7 months after it was released!) can continue to be very useful because of an active developer/hacker community. I do encounter these longings to have the latest greatest devices, but I am also beginning to see much more challenge/fun/value in being able to keep lower end hardware useful through better software.

The more I have a smartphone the less I want to be without one. It is interesting how my computer usage habits are changing because of it. Maybe a topic for another post.

week of year in jqueryUI datepicker

June 23rd, 2010

I needed to display week of year in a colum on the jqueryUI datepicker. Luckily it has the feature built in, unluckily it has a quirk relative to the way we typically display calendars in the US with Sunday as the first day colum. At first I thought it was a bug, but technically it is not, so I guess it is better classified as a gotcha. Anyway, to get the week of year to display as we would expect in the US you need two pieces.

First where you instantiate the datepicker:

$(".uiDatePicker").datepicker({minDate: -1, maxDate: '+10D', defaultDate: +1, hideIfNoPrevNext: true, showWeek: true, calculateWeek: myWeekCalc });

The important argument there is the ‘calculateWeek: myWeekCalc’ .

Next you need to define the custom week of year calculator, in this case ‘myWeekCalc’:

function myWeekCalc(date) {
  var checkDate = new Date(date.getTime());
  // Find Thursday of this week starting on Sunday
  checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay()));
  var time = checkDate.getTime();
  checkDate.setMonth(0); // Compare with Jan 1
  checkDate.setDate(1);
  return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
}

I borrowed this from the jqueyUI source and tweaked it to calculate the week based on the Thursday in the row instead of the first day colum in the row. To me this makes sense given the way the ISO for week of year is determined.

It seems to be working perfectly for me. Let me know if you use this and run into issues :)

Customizing The Ubuntu Terminal

May 31st, 2010

The Obvious:

With a terminal open select Edit -> Profile Preferences.

In here you can set background color, transparency, font, font-size, text colors and more.

A couple not-quite obvious things I like to do.

Uncheck the ‘show menubar by default in new terminals’ – it just isn’t very useful and a right click in the terminal gives you some of those options anyway and if what you need is not there you can easily bring back the menubar from there.

Increase the number of scrollback lines – personally I at least double it to 1024 lines as Grails errors are long and ugly and that is the framework I spend a lot of my time working with. Your mileage may vary.

Advanced:

The .bashrc file in your home directory is where extra configuration options lie.

Colors:

Ubuntu disables the prompt being a different color. but simply uncomment the proper line in .bashrc and you’ll undo that. Look in the vicinity of line 36-40. The comment says the goal is to avoid distraction… just doesn’t make sense to me. A colored prompt helps me distinguish certain pieces of text from others, so for me, it is essentially the opposite of a distraction helping me focus on the pieces I need to read from the pieces I don’t.

Aliases:

Many Linux command line gurus expect “ll” or certain other common aliases to work. Uncomment a couple more lines in Ubuntu’s .bashrc file and they will. Look in the vicinity of line 80-83.

you’ll also see just a couple lines down:

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
So if you’d like to add extra aliases create a .bash_aliases file and fill it in. Sweet right?!

Starting and Stopping Development Server on Laptop

April 28th, 2010

I am not sure how much battery life suffers on my laptop when it is unnecessarily running Apache, PostgreSQL and MySQL, but the databases consistently show up in the list when I use PowerTop, so it is probably not insignificant. Anyway, since I knew it couldn’t be to hard to shut them down and start them up again when I needed to, I wrote a couple little bash scripts to do the job.

LampStart.sh

  #sudo /etc/init.d/mysql start
  sudo service mysql start
  sudo /etc/init.d/postgresql-8.4 start
  sudo /etc/init.d/apache2 start

LampStop.sh

  #sudo /etc/init.d/mysql stop
  sudo service mysql stop
  sudo /etc/init.d/postgresql-8.4 stop
  sudo /etc/init.d/apache2 stop

To reuse these you might have to modify them for your particular server setup, but that would be relatively easy. The other thing I did is to make them executable. Then I put them on my desktop and I treat them like simple switches. click on, click off. easy!

All this made me think again about the merits of using something like XAMPP for development environments. Not really sure what I would lose or gain by doing that, but one thing I do remember from my Windows days when I used it that it had a control panel with lots of handy on/off/restart switches.

Linux Mint 7 Gloria

May 23rd, 2009

I am very excited about the pending release of Linux Mint 7 “Gloria”. I plan to do a fresh install with it on my main work desktop when the release drops. Mint is a well polished and subtly but well improved version of Ubuntu. It’s releases tend to lag a month or so behind Ubuntu, but it seems like they use that time well. In my experience Mint has been more stable, better looking, and more complete in its features.

I was thinking this morning as I was looking at reviews of the Ubuntu Netbook Remix, “I wonder if Mint will have a netbook remix version.” That would probably be pretty cool, even though I don’t personally have a netbook to benefit from something like that. What might be better is if some of the specialized netbook distros like eeebuntu would learn a thing or two from Mint or maybe use Mint as their base distro.

The next thought was that system76, a company that sells ubuntu laptops, should use Mint instead. There are probably good reasons for them to stick with a mainline distro though, for example they also make servers and Linux Mint is really meant as a desktop OS. So maybe there should be a company that makes just a small hanful of machines that are designed for Linux Mint. I know I would be very interested in a laptop that was designed and built to the same types of quality standards as the Mint distro itself. I am thinking something comparable to Apple’s laptops. In my mind such a product would be a real competitor in the market as well. Maybe somebody with time and ambition will read this and be inspired…

Learning XHTML and CSS

May 21st, 2009

a few of my co-workers wanted to know XHTML and CSS a little better, and I got asked to teach them some of what I know. I put together a little presentation, and I thought it might be worth sharing.

learningXHTML-CSS

had to convert it to PDF thanks to wordpress.com not accepting open document presentation format (Boo – hiss!)

Why this blog?

April 26th, 2009

Just setting up up a place to blog specifically about web development, and open source stuff. Maybe more specifically Iwill attempt to make posts here about doing web development using open source tools. I use Ubuntu and associted software to do most of my work, and I feel like there are often things worth pointing out to others in the same situation or to convince others that this is a good way to do development. Realistically I probably won’t be posting stuff all that often.

Sure I could host a wordpress blog myself, but that is more than I want to worry about. Hosting it here on wordpress.com lets me worry less about maintaining a blog. I will use the time and effort saved to try to write stuff worth reading.