Martin Gladdish

Software 'n' stuff

Configuring Logback via Groovy in an SBT Project

I wanted to use logback for my tests’ logging on an SBT project recently, and it took a little while to work out how best to do it. The good news is that it turns out to be simple enough (once you know what to do).

In your build.sbt add dependencies for Groovy and Logback Classic (I have restricted them just to ‘test’ scope as I only want this to apply to my tests)

1
2
3
4
5
...

libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.1.2" % "test"

libraryDependencies += "org.codehaus.groovy" % "groovy-all" % "2.4.1" % "test"

Then put your logback.groovy in the root of your /test/resources folder.

That’s it - logging during test execution should now be under the control of your logback.groovy config.

Watermelon Reporting

“Watermelon reporting” is a lovely phrase I heard for the first time the other day.

Everything’s red in the centre of the organisation, gradually changing colour as you go up through the layers until it’s nice and bright green on the outside. Don’t worry boss, the reports are all looking good…

http://blog.scrumphony.com/2011/02/watermelon-reporting/

Testing Jsr303 Annotated Beans

I have been looking at using jsr303 annotations to mark up some of my beans. The good news is that both Hibernate and Spring play nicely with these annotations, and will validate them at appropriate times. The bad news is that the examples of testing these annotations that I have found online so far look cumbersome and awkward.

Let’s take a simple example:

simple java bean with a single jsr303 annotation
1
2
3
4
5
6
7
8
9
10
public class SimpleBean {
    @NotNull
    private Long id;
    private String name;

    public SimpleBean(Long id, String name) {
        this.id = id; this.name = name;
    }
    // getters and setters...
}

This is fine so far and we have the possibility that the constructor could be passed a null id. So, let’s write a unit test that ensures our validation will barf.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class SimpleBeanTest {

    private Validator validator;

    @Before
    public void setUp() {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    @Test
    public void nullIdMustThrowValidationError() {
        SimpleBean bean = new SimpleBean(null, "valid string");
        Set<ConstraintViolation<SimpleBean>> violations = validator.validate(bean);
        assertThat(violations.size(), equalTo(1));
    }
}

If this test fails, we get something like this as the result:

1
2
3
4
java.lang.AssertionError: 
Expected: <1>
     but: was <0>
  ...

Not so pretty. This is where hamcrest’s matcher toolkit comes in handy. What if we could write our test like this instead?

unit test with custom validations matcher
1
2
3
4
5
6
7
public class SimpleBeanTest {
    @Test
    public void nullIdMustThrowValdationError() {
        SimpleBean bean = new SimpleBean(null, "valid string");
        assertThat(bean, hasNoViolations());
    }
}

A matcher implementation could look like this

custom jsr303 validation matcher
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class JSR303NoViolationsMatcher<T> extends TypeSafeMatcher<T> {

    private Validator validator;
    private Set<ConstraintViolation<T>> violations;

    public JSR303NoViolationsMatcher() {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    @Override
    protected boolean matchesSafely(T t) {
        violations = validator.validate(t);
        return violations.size() == 0;
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("no jsr303 validation violations");
    }

    @Override
    protected void describeMismatchSafely(Object item, Description mismatchDescription) {
        mismatchDescription.appendText("was ").appendValue(violations);
    }

    @Factory
    public static JSR303NoViolationsMatcher hasNoViolations() {
        return new JSR303NoViolationsMatcher();
    }
}

And our new-look test spits out the following upon failure:

1
2
3
java.lang.AssertionError: 
Expected: no jsr303 validation violations
     but: was <[ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=id, rootBeanClass=class com.example.SimpleBean, messageTemplate='{javax.validation.constraints.NotNull.message}'}]>

There. Much nicer. Not only do we know that the test failed, but we are immediately told how it failed.

Thanks to planetgeek for a nice article about writing custom hamcrest matchers.

Using Typesafe Role Enums With Spring Security

Spring Security is a seriously useful tool but one of the things that has been nagging away at the back of my mind about it is that it is so heavily reliant on magic strings. Take a typical example:

spring security config fragment
1
2
3
4
5
6
<http>
    <intercept-url pattern="/**" access="ROLE_USER"/>
    ...
</http>

<global-method-security pre-post-annotations="enabled"/>

This configures all URLs in the application to require that the user is logged in and has the privilege named ROLE_USER.

sensitive method
1
2
3
4
@PreAuthorize("hasRole('ROLE_SYSADMIN')")
public String getSensitiveInformation() {
    return "Only special people are allowed to see this information";
}

This ensures that anyone calling this method (either directly or indirectly) must be logged in and have the privilege named ROLE_SYSADMIN.

So far, so straightforward.

The problem is that these role names proliferate across the codebase. Chances are you will want to refer to the same role name in many different places in your application. If these role names were in code, you would typically refactor them out into a single representation as soon as you had two different references to them in the codebase. Unfortunately, this is not so simple with Spring Security.

The good news is that it is possible.

Authority enum
1
2
3
4
5
6
package com.example;

public enum Authority {
    USER,
    SYSADMIN
}

Which can be referred to in Spring’s expression language like this:

spring security config using role enum
1
2
3
4
<http use-expressions="true">
    <intercept-url pattern="/**" access="hasRole(T(com.example.Authority).USER.toString())">
    ...
</http>

And similarly on method annotations

sensitive method with typesafe role enum
1
2
3
4
@PreAuthorize("hasRole(T(com.example.Authority).SYSADMIN.toString())")
public String getSensitiveInformation() {
    return "Still only special people are allowed to see this information";
}

Unfortunately IntelliJ Community Edition’s ‘Find Usages’ is not clever enough to return these Spring expression language references, but it does at least feel better than sprinkling identical magic strings across the codebase.

Inline Editing Forms With Javascript

I have picked up some contracting work to build a new web site. It is very early days and I am just putting together some initial workable web forms at the moment and want something for editing information that would be a little less ugly than just presenting a standard set of populated html form controls. Instead, I like the idea that the information will be written to the page as normal text, but clicking on it will allow you to change the value inline. After a little poking about, there appear to be two main contenders to help implement this in JQuery, Jeditable and Editable.

Feature comparison of Jeditable and Editable JQuery plugins
JeditableEditable
html 5 form elementsnono
extendable input typesyes,
via inbuilt addInputType method
yes,
by modifying the source directly
default POST data formatid:element_id value:element_valuenone

Adding html5 input types

Editable

Editable does at least provide an editableFactory in its source which is intended to be extended. Although easy to do, it still doesn’t get around the fundamental problem of having to modify the source itself.

modifying .editableFactory directly to handle ‘url’ input types
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$.editableFactory = {
  'text': {
      toEditable: function($this,options){
          $('<input/>').appendTo($this)
                       .val($this.data('editable.current'));
      },
      getValue: function($this,options){
          return $this.children().val();
      }
  },
  // adding custom support for <input type="url">
  'url': {
      toEditable: function($this,options){
          $('<input type="url"/>').appendTo($this)
                       .val($this.data('editable.current'));
      },
      getValue: function($this,options){
          return $this.children().val();
      }
  },
  // end of added block
  ...

Jeditable

There really is not much in it in terms of complexity or verboseness between the two implementations, but the fact that Jeditable allows extensions without modifying its source swings it for me.

Extending Jeditable’s set of supported input types
1
2
3
4
5
6
7
8
9
<script type="text/javascript">
    $.editable.addInputType('url', {
        element : function(settings, original) {
            var input = $('<input type="url">');
            $(this).append(input);
            return(input);
        }
    });
</script>

Posting changes back to the server

Both of the following examples work with the following template. You will also notice that this is not plain html, but a velocity template. The template is served from a spring/velocity application, more details of which will follow in later posts.

1
2
#springBind("myDomainObject.url")
<span class="editableURL">$status.value</span>

Editable

Although Editable doesn’t support this out of the box, it is pretty straightforward.

1
2
3
4
5
6
7
8
9
<script type="text/javascript">
    $(document).ready(function() {
        $('.editableURL').editable({type:'url', submit:'save', cancel:'cancel', onSubmit:end});
    });

    function end(content) {
        $.post(window.location.href, {url: content.current});
    }
</script>

So we wait for the document to be loaded by the browser, then decorate all elements with the “editableURL” class with Editable’s behaviour. The end function is triggered when you submit your change, and is responsible for POSTing the data back to the server. Note that, in this example, data is POSTed back to the same URL from which the page was served.

All in all, this is rather nice, and we have complete control over the data passed back to our server.

Jeditable

As mentioned in the comparison table above, Jeditable by default will POST data in the format id: element_id, value: element_value. This is fine for table-based data in which every field has an id, but a long way from OK for our domain-object-backed Spring application. The good news is that we get complete control over Jeditable’s POST behaviour, too.

1
2
3
4
5
6
7
8
<script type="text/javascript">
    $(document).ready(function() {
        $('.editableURL').editable(function(value, settings) {
            $.post(window.location.href, {url: value});
            return(value);
        }, {submit: 'save', type: 'url'});
    });
</script>

This snippet works broadly the same way, with the added control that the return value of the function is what is used as the new value displayed on the page. I can’t make up my mind whether this is a good thing. As the script stands, if the server encounters an error updating the field, then the new value will be displayed on the page and the user will be none the wiser that anything went wrong.

Conclusion

Although Editable is arguably preferred by Stack Overflow users, there is a little snag with both of them. Neither library seems to handle keyboard navigation particularly well (at least in Chrome on OS X). Editable’s submit and cancel buttons do nothing when they are triggered by receiving focus and hitting the spacebar, whereas Jeditable’s support is better in that the buttons do work, just that you have to be quick about it. If you leave the focus on the button for more than a second or so then it assumes you have given up and cancels the edit, taking away the form control again.

All in all, Jeditable seems to suit my preferences a little better. Its public revision control and nicer web site also make it seem just that little bit more polished. The only negative point, and it is a small one, is that Jeditable doesn’t provide a labelled version number. Judging by the readme on github it is up to version 1.7.2 at the time of writing, so that is the number I inserted into the filename myself before using it.

A complete example of using Jeditable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!DOCTYPE html>
<html>
    <head>
        <title>Inline editing forms with JQuery and Jeditable</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
        <script src="/{your_path_here}/jquery.jeditable-1.7.2.mini.js" type="text/javascript"></script>
    </head>
    <body>
        #springBind("myDomainObject.url")
        <span class="editableURL">$status.value</span>

        <script type="text/javascript">
            $.editable.addInputType('url', {
                element : function(settings, original) {
                    var input = $('<input type="url">');
                    $(this).append(input);
                    return(input);
                }
            });
        </script>

        <script type="text/javascript">
            $(document).ready(function() {
                $('.editableURL').editable(function(value, settings) {
                    $.post(window.location.href, {url: value});
                    return(value);
                }, {submit: 'save', type: 'url'});
            });
        </script>

    </body>
</html>