Warsjawa – warsztaty prawie pełne

W błyskawicznym tempie zapełniają się miejsca na warsztatach Warsjawy prowadzonych m.in. przez ekipę TouK. Mimo że rejestracja na tę popularną jesienną imprezę javową została otwarta zaledwie wczoraj, żeby się załapać, trzeba zdecydowanie się pospieszyć. Poniżej lista toukowych prelegentów.

Dominik Wiernicki – Wicket
Bartek Zdanowski – vert.x + raspberry pi
Maciek Próchniak – Akka
Mateusz Kaczmarek, Michał Trzaskowski – Testowanie użyteczności z wykorzystaniem użytkowników
Krzysztof Siejkowski w duecie z Maciejem Górsk m – Android^2 – do potęgi Square i Google APIs
Paweł Byszewski – Dependecy Injection for Android with Roboguice
Marcin Cylke – Big Data w czasie rzeczywistym – wstęp do Storm

Z pełną agendą można zapoznać się na stronie Warsjawy. Konferencja odbędzie się już 12 października 2013 roku. Tradycyjnie za darmo (po wcześniejszej rejestracji), tradycyjnie na gościnnym Wydziale Matematyki, Informatyki i Mechaniki Uniwersytetu Warszawskiego, TouK – sponsorem. Też tradycyjnie:) W przerwach między warsztatami zapraszamy do odwiedzenia naszego stoiska.

You May Also Like

Simple trick to DRY your Grails controller

Grails controllers are not very DRY. It's easy to find duplicated code fragments in default generated controller. Take a look at code sample below. It is duplicated four times in show, edit, update and delete actions:

class BookController {
def show() {
def bookInstance = Book.get(params.id)
if (!bookInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])
redirect(action: "list")
return
}
[bookInstance: bookInstance]
}
}

Why is it duplicated?

There is a reason for that duplication, though. If you move this snippet to a method, it can redirect to "list" action, but it can't prevent controller from further execution. After you call redirect, response status changes to 302, but after method exits, controller still runs subsequent code.

Solution

At TouK we've implemented a simple trick to resolve that situation:

  1. wrap everything with a simple withStoppingOnRender method,
  2. whenever you want to render or redirect AND stop controller execution - throw EndRenderingException.

We call it Big Return - return from a method and return from a controller at once. Here is how it works:

class BookController {
def show(Long id) {
withStoppingOnRender {
Book bookInstance = Book.get(id)
validateInstanceExists(bookInstance)
[bookInstance: bookInstance]
}
}

protected Object withStoppingOnRender(Closure closure) {
try {
return closure.call()
} catch (EndRenderingException e) {}
}

private void validateInstanceExists(Book instance) {
if (!instance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])
redirect(action: "list")
throw new EndRenderingException()
}
}
}

class EndRenderingException extends RuntimeException {}

Example usage

For simple CRUD controllers, you can use this solution and create some BaseController class for your controllers. We use withStoppingOnRender in every controller so code doesn't look like a spaghetti, we follow DRY principle and code is self-documented. Win-win-win! Here is a more complex example:

class DealerController {
@Transactional
def update() {
withStoppingOnRender {
Dealer dealerInstance = Dealer.get(params.id)
validateInstanceExists(dealerInstance)
validateAccountInExternalService(dealerInstance)
checkIfInstanceWasConcurrentlyModified(dealerInstance, params.version)
dealerInstance.properties = params
saveUpdatedInstance(dealerInstance)
redirectToAfterUpdate(dealerInstance)
}
}
}
Read More

Confitura 2022 Summary

Confitura is definitely about people and community for us. There was a possibility to meet with TouKs (this is our name for ourselves) who work mostly remotely, friends, future co-workers, and also to reunite with ex-TouKs.