Removing boilerplate (Lombok)
Java has a — probably deserved — reputation for being somewhat prone to boilerplate, obscuring the meaning of our code. There are however a couple of techniques we can use to reduce the boilerplate load.
One of the most common areas of boilerplate is the getters and setters. We can use project lombok to remove the necessity of writing these methods.
Exercise
-
in the
pom.xml
, add the following to<dependencies>
:<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.18</version> <scope>provided</scope> </dependency>
-
remove the getters and setters for
Owner#name
and add in its@lombok.Getter
and@lombok.Setter
annotations for its field instead:@javax.jdo.annotations.Column(allowsNull = "false", length = 40) @Property(editing = Editing.DISABLED) @Title(prepend = "Object: ") @Getter @Setter (1) private String name;
1 added in, getName()
andsetName()
removed -
do likewise for the
Owner#notes
property
Removing boilerplate (Parameter names)
Apache Isis uses Java reflection to infer the names of domain object types and members. However, prior to Java 8 the name of method parameters was not accessible, and thus an annotation is required to provide this information.
For example, the Owners#findByName(…)
action is:
public class Owners {
@Action(semantics = SemanticsOf.NON_IDEMPOTENT)
@MemberOrder(sequence = "1")
public Owner create(
@Parameter(maxLength = 40)
@ParameterLayout(named = "Name")
final String name) {
return repositoryService.persist(new Owner(name));
}
...
}
The boilerplate here is the @ParameterLayout#named
annotation.
Given we’re running on Java 8, though, we can remove this boilerplate. We do so by configuring the framework to also check for Java 8 metadata.
Exercise
-
in the IDE, ensure that the compiler specifies the
-parameters
flag.For example, in IntelliJ:
-
in the
pom.xml
, add the following to<dependencies>
:<dependency> <groupId>org.isisaddons.metamodel.paraname8</groupId> <artifactId>isis-metamodel-paraname8-dom</artifactId> <version>1.16.2</version> </dependency>
-
in the
isis-non-changing.properties
file, add:isis.reflector.facets.include=\ org.isisaddons.metamodel.paraname8.NamedFacetOnParameterParaname8Factory
This extends the metamodel processing to use the new Java 8 reflection API.
There’s further discussion on configuration properties in the next section.
-
Delete the
@ParameterLayout(named=…)
attribute wherever it is now redundant.
Run the application and make sure it still runs fine.
Disable editing
The framework is configured using various properties files.
The archetype splits these into an isis-non-changing.properties
file, and an isis.properties
file (under WEB-INF
).
The former is configuration properties that don’t vary by environment, the latter contains properties that will vary by environment (eg database connection parameters).
All of these configuration properties can be overridden using system properties. |
The isis-non-changing.properties
file includes this setting:
isis.objects.editing=false
This means that properties are non-editable by default, a good convention because in most cases we will want to use actions to mutate the state of the system.
In Order
we can therefore remove some boilerplate:
@javax.jdo.annotations.Column(allowsNull = "false", length = 40)
@Property(editing = Editing.DISABLED)
@Title(prepend = "Object: ")
@Getter @Setter
private String name;
Since editing is disabled by default, we can therefore remove the editing = Editing.DISABLED
attribute.
Exercise
-
remove the
editing = Editing.DISABLED
attribute:@javax.jdo.annotations.Column(allowsNull = "false", length = 40) @Property @Title(prepend = "Object: ") @Getter @Setter private String name;
We could in fact remove
@Property
annotation entirely because the framework searches only for getters and setters. It’s a matter of taste.
Font Awesome Icons
While we are looking at isis-non-changing.prooperties
, note that there is another configuration setting for font-awesome icons:
isis.reflector.facet.cssClassFa.patterns=\
new.*:fa-plus,\
add.*:fa-plus-square,\
create.*:fa-plus,\
update.*:fa-edit,\
delete.*:fa-trash,\
find.*:fa-search,\
list.*:fa-list
This is what causes the framework to automatically include icons for specifically named action names.
Similarly, bootstrap "btn" classes can also be associated with action names:
isis.reflector.facet.cssClass.patterns=\
delete.*:btn-danger
This UI hint can be specified using either annotations or the .layout.xml
files, but specifying it centrally removes the boilerplate clutter and is a good way of ensuring consistent verbs are chosen for action names.
Implicit Action Annotations
Apache Isis has two ways to recognise actions, either by those that are explicitly annotated with @Action
annotation, or alternatively implicitly as all public
methods that do not otherwise represent properties, collections or supporting methods.
The archetype is configured to use the former, but we can switch to implicit actions and potentially save the need to add @Action
annotation.
Also (and probably more useful), in implicit mode the framework will tell us if we accidentally mis-spell any of the supporting methods (which we’ll see later in the tutorial).