Tuesday, November 17, 2009

Problem with POI-Excel Fonts solved!

Today suddenly i get the following error opening a POI-generated file with Microsoft Excel:


"Excel cannot complete this task with available resources. Choose less data or close other applications."


More info in: http://markmail.org/message/bzy5wv2bziodqeoi

The solution was:

1.- Reuse evey Font object you can...
Someting like this:

for (row in rows) {
font = workbook.createFont()
//Do whatever with font
}


Have to be refactored to something like this:

font = workbook.createFont()
for (row in rows) {
//Do whatever with font
}


2.- Update to 3.5-FINAL version. 3.2-FINAL version is buggy and exhausts all Excel resources with anything you do.

NOTE: With OpenOffice everything worked ok.

Friday, November 13, 2009

Annotations and bean validation with Groovy

I was looking for something like annotations driven validation for Groovy. Something like JSR-175 but... without JSR-175. Maybe something like Spring Validator would be nice but... without Spring.
Something like this:


class FooBeanWithValidations {

@NotEmpty
String id

}

I have reviewed some options, but i was looking for somthing very simple and plain...so, finally, i have to write it by myself...
First I defined the annotation class:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface NotEmpty {

}

And then i writed a Validation class which handles the annotations and performs validation logic:

class Validator {

/**
* Helper method for apply a closure over all annotated bean properties
*/
protected static def forEachAnnotatedField(def clazz, def annotationClass, def closure) {

if (clazz in [Object, GroovyObject]) {
return
}

def properties = clazz.declaredFields
def annotated = []
annotated.addAll(properties.findAll {field ->
def annot = field.annotations.find {annotation->
return (annotationClass.isAssignableFrom(annotation.class))
}

if (annot){
closure(field, annot, clazz)
}
})

forEachAnnotatedField(clazz.superclass, annotationClass, closure)
}


/**
* Perform NonEmpty validations
*/
static def validateNotEmpty(def bean) {

forEachAnnotatedField (bean.class, NotEmpty.class) {field, annotation, clazz ->
def value = bean."${field.name}"

//Be aware with boolean values. False value are not empties!!
if (value instanceof Boolean) {
return
}

if (!value){
throw new ValidationException(bean, field.name, null)
}
}
}

static def validate(def bean) {

//Call other validation methods
validateNotEmpty(bean)
}

}

And voila... you can call validate method over any bean using Groovy Categories:

def bean = new FooBeanWithValidations()
use(Validator) {
bean.validate()
}

Or you can inject a validation method int bean's MetaClass

FooBeanWithValidations.metaClass.validate = {Validator.validate(this)}