Business Problem Solver using 0s and 1s aka Software Developer

Tag: java

Java 8 default methods can be a handy tool for refactoring interface contracts. You can use this trick in case you want to add a new interface method that can be expressed in terms of an existing one. You don’t want to change the implementors of the interface (at least for now).

Let’s take an example on a interface (Loader) with a mis-defined contract. Instead of getting levels where a Loader can be applied to, I wanted the loader to answer this question directly.

Now this method doesn’t make our intent any clearer and can be safely inlined.

This refactoring didn’t break the implementors of the Loader interface. The next step would be to implement the shouldBeAppliedOn method in all Loader derivates. When done, I could convert the default method to an abstract method (i.e. remove its body) and remove the original method (getLevelsToBeAppliedOn).

Hot and cold Observables

When creating an Interval Observable, I thought it will start ticking (emitting) immediately after creation. Wrong! There are hot and cold Observables. Hot Observables start firing events immediately. Cold Observables, only when there is at least one subscriber. Interval is cold – you have to connect an Observer first.

Operators

Docs and marble diagrams are the best source of information about transforming Observables.

Pure streams and side effects

When you connect an Observer to an Observable, every item emitted by the source is passed to the onNext Observer method. There are no restrictions on what you can put in the onNext handler. On the other hand, there are do callbacks, which can act similarly to onNext.

In my pet project, TimeSlice class creates a tick stream transformed previously with pure functions. Main class adds impure console and Growl notifications to the stream in do callbacks. In this way I can unit test the Observable produced by the TimeSlice class using the provided TestScheduler (more on this in the next section).

Testing

Want to be a master of time? Test your Observables with TestScheduler. You will be able to advance time and gather all items produced by the Observable under test. Check the TimeSliceTest class for usage examples.

Backpressure

Backpressure is a way to deal with an Observable that produces items too rapidly (or too slowly).

In my case I wanted to pause the interval Observable and resume its activity. I didn’t find a direct way (i.e. through any of RxJava interfaces), so I asked on Stack Overflow. The solution consists in filtering the Observable by a boolean “semaphore” toggled from outside.

What I want to do

Given a form in an Android activity or dialog, convert form values (java.lang.Strings) to domain classes and validate if they fulfill business constraints

Don’t validate if there is a conversion error

Chain validators

Perform complex validations (e.g. of two dependent fields)

Solution with Option monad

I encapsulated a form value coming from a visual component (it can be an EditText, Spinner, whatever) in the FormValue monadic type. This is a straight implementation of the Option monad with two subtypes:

If you go back to the implementation of FormValue.validateWith, you may notice that Validator.validate will be called only for Some value. In case of None (resulting e.g. from a wrong conversion), validateWith returns the same None object.

Complete example – conversion + validation

We convert the SSN field to SSN and check if it’s valid. In case of errors (during conversion or validation), an error message will be displayed in a Toast.

Is it really a monad?

If a type wants to be a monad, it has to have:

unit operation that “wraps” a value with monad. It can be a constructor or a factory method. In our case FormValue.some represents the unit operation

bind operation transforming the monad into a next monad, exposing its internal value for a transformation function. FormValue.validateWith does this. Because Java doesn’t have first-class functions, we represent the validateWith operation argument as a method object – Validator

In case of Some, calling validateWith (bind method) with this Validator will return a new Some monad holding the same value. None‘s implementation returns always the same monad instance. Hence the first law is fulfilled.

unit – unit must preserve the value inside the monad

unit(x).bind(f) ≡ f(x)

unit(x) corresponds to FormValue.some(x). Result of the execution of Some.validateWith is equivalent to the execution of the provided Validator:

As you can see the result of the validation in the anonymous class is the same as of the expression expanded above.

Conclusions

Monads look abstract, esoteric, and, I admit, a little scary. Although from the functional programming domain, they can be implemented in imperative languages. They solve real-life problems (converstion and validation) in an elegant manner (we chained converters and validators with few ifs and no null checking).

low added filtering overhead – reading 100.000 CSV lines and storing them in the database using Hibernate took us less than 30 seconds

During the development I had to overcome some hurdles imposed by Smooks processing model. In this post I would like to share my practical experience I gained working with Smooks. First, I’m going to present a sample transformation use case with requirements similar to a real-world assignment. Then I will present solutions to these requirements in a ‘how-to’ style.

Use case

We are developing a ticketing application. The heart of your application is Issue class:

We have to write an import and conversion module for an external ticketing system. Data comes in the CSV format (for the sake of simplicity). The domain model of the external system is slightly different than ours; however, issues coming from the external issue tracker can be mapped to our Issues.

External system exchange format defines the following fields: description, priority, reporter, assignee, createdDate, createdTime, updatedDate, updatedTime. They should be mapped to our Issue in the following manner:

description property – description field

This is a simple Smooks mapping. No big issue.

project property – there is no project field. Project should be assigned manually

Before diving into details, I’m going to present the final Smooks configuration and the invocation code of the transformation (as JUnit 4 test). Later on, in each recipe, I will explain the XML configuration and Java code fragments relevant to that recipe.

The remaining classes (Issue, Priority, Project, IssuePrioritizer) are not included in the text. You can browse online the source code in GitHub. To get your local copy, clone the Git repository:

Set compound properties in Java binding

It is not possible to map directly two source fields to a Java bean property. Java bindings with and are executed on a SAX visitAfter event bound to to a single XML element/CSV field. We have to define a binding for a helper Map bean with the fields we want to merge:

The advantage of this approach is that you make use of Smooks decoder infrastructure. You can configure the transformation with your own decoders (e.g. custom java.util.Date allowing to specify multiple date formats). If you are using the built-in DateDecoder, you can catch and handle a standard DataDecodeException.

The disadvantage is that you have to change your domain model code. New methods add complexity and must be unit tested, especially in cases when only one of partial setter is called.

In the second solution, you define a binding for a helper Map bean with the date and time fields. In the right binding you use an MVEL expression concatenating date and time strings and converting them to Date (e.g. using a java.text.SimpleDateFormat instance):

The advantages of the first solution are disadvantages of the second one. You don’t touch your Java classes. It is simple – you have to specify only the Smooks configuration. In case of handling of many date/time formats and their combinations, the MVEL expression defining the conversion can become complicated. In case of an exception, you won’t get DataDecodeException, but an ugly, generic ExpressionEvaluationException.

Conclusions

Smooks is a great library that will save you writing a lot of code in case of processing many different formats. With a few lines of code and the XML configuration you will be able to read a file and persist its contents in the database using your favourite ORM framework.

However, Smooks processing model and its usage in built-in cartridges make sometimes difficult to configure the transformation for a real world requirement. The information provided in the user guide is sometimes scarce and unclear. I hope these practical cases will help you use Smooks Java bean mappings and MVEL expressions more effectively.

Comments

This article is published also on my employer’s blog. Please post all comments there.

I was using custom font in a customer report embedded in the web application. The font (available in the operating system) was displayed correctly in HTML, RTF and Excel export. However, in the generated PDF text elements were displayed using Arial font.

The solution is to wrap required fonts as JasperReports Font Extensions. Font TTF files can be included in the same project generating Jasper reports or, a more elegant solution, in a separate JAR file.

I found an interesting blog post Fonts in JasperServer about providing custom fonts. The author is configuring the font extensions using Spring. However, you can do it in a simpler way.

First, install fonts in iReport and let create it the required configuration. In iReport, go to Tools -> Options, click on iReport group and go to Fonts tab. Here are some screenshots from the installation wizard:

iReport creates font extensions configuration and copies the recently installed font into the iReport installation directory/ireport/fonts directory (C:\Program Files (x86)\iReport-3.7.2\ireport\fonts in my case). You should find the following files there:

jasperreports_extension.properties – it configures net.sf.jasperreports.extensions.ExtensionsRegistryFactory as net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory and points to the font family configuration:

After that, the fonts contained it JAR will be available to JasperReports when generating a PDF report.

Update:
Just before publishing my post, Matt Dahlmann, author of the published an update of his previous article mentioned in this post. Check Jaspersoft v3 Font Extensions for the more actual version.