Introducing JShell and Its API

One of the new features in Java 9 is called ‘JShell’ and it’s awesome. It is basically a Read–Eval–Print Loop (REPL) implementation for the Java language.

You can run JShell in a command line environment (command prompt (cmd) on Windows, Terminal on Mac). If your JAVA_HOME path is set correctly, you could simply type in ‘jshell’ and hit enter. You can find the executable in the jdk-9.jdk/Contents/Home/bin directory.

JShell in Terminal
A launched Terminal instance with JShell running.

Imports

A good thing to keep in mind is the fact that a freshly opened session comes with multiple imports:

jshell> /imports
|    import java.io.*
|    import java.math.*
|    import java.net.*
|    import java.nio.file.*
|    import java.util.*
|    import java.util.concurrent.*
|    import java.util.function.*
|    import java.util.prefs.*
|    import java.util.regex.*
|    import java.util.stream.*

You might as well add any other import. Syntax: import your.package.name.

Expressions and Variables

Since JShell is a Java interpreter, any valid Java expression will be accepted. Find an example expression testing String equality.

jshell> "Hello".equals("World")
$1 ==> false

The result in this obvious example returns false. Note that a variable $1 has been created as well. Execute a similar expression again and you’ll see another variable has been created. Notice the incremental naming ($2 and so on). Creating your own named variables is as easy as:

jshell> String myVariable = "awesome"

Keeping track of all your variables can be done using the /vars command:

jshell> /vars
|    boolean $1 = false
|    boolean $2 = false
|    String myVariable = "awesome"

Methods

Creating or replacing methods is done simply by inputting the entire method definition. Below example creates a method to print any given String and executes it afterwards.

jshell> void printSomething(String s) { System.out.println(s); }
|  created method printSomething(String)

jshell> printSomething("Hi there!")
Hi there!

Listing methods can be done in a way similar to listing variables, using the command /methods.

If you have a long method to edit, I invite you to use /edit <nameOfMethod>. This will open an external editor that is slightly easier to work with for long snippets. Use /edit without parameters to edit the entire anything in the current state. To reset your entire JShell state, use /reset.

Scripting

Have bigger snippets to evaluate? Consider playing around with scripts, which have the <script>.jsh format. To create a script you could simply create a file from scratch or you could issue the command: /save mySnippets.jsh, which saves your current state into the given file.

Say our mySnippets.jsh looks like this:

"Hello".equals("World");
$1 == true
System.out.println("$1 is " + $1 + " and $2 is " + $2)
String myVariable = "awesome";
void printSomething(String s) { System.out.println(s); }
printSomething("Hi there!")

Then we could run (load) it using the /open command.

jshell> /open mySnippets.jsh
$1 is false and $2 is false
Hi there!
awesome

Plenty more advanced stuff you could do with JShell scripts. You might as well be interested in setting a particular script as your starting state, but I’ll leave that as an exercise for the reader.

JShell API

Interpreting Java code within a Java application is now possible using Java 9’s built-in jd.jshell API! Use it for small code evaluations or to run scripts.

I won’t go over this part in depth, because it’s rather self explanatory. However I’ll give a very basic example (you could’ve probably figured out on your own).

import java.util.List;
import jdk.jshell.JShell;
import jdk.jshell.SnippetEvent;

public class Main {

    public static void main(String[] args) {
        try (JShell js = JShell.create()) {
            int yearsOld = 5;
            List<SnippetEvent> snippetEvents = js.eval("String.format(\"I'm %d years old!\", " + yearsOld + ")");
            snippetEvents.forEach(snippetEvent -> System.out.println(snippetEvent.value()));
        }
    }
}

To run scripts, I’ll gladly refer to DZone’s article to get you started extremely quickly. In their code sample you will be able to run any script you provide to their executor implementation. It also comes with some basic event handling (handling failing evaluations). However running their example I noticed that all statements in the provided script must end with a semicolon, otherwise your output might end up looking like Evaluation failed : Snippet:ErroneousKey#1-"Hello".equals("World").

Conclusion

The power of instant expression evaluation feedback surely is useful. I can imagine myself using JShell for quick checks on String formats and small stuff like that. Besides that, I like the fact that the the new feature along with its API support scripting. You could have a static code base that calls scripts that can be changed whenever necessary.

Obviously this is just JShell in a nutshell (that could’ve been a great post title as well I reckon!) and there’s much more to it. The purpose of this post was to quickly go over the very basics and to show the new feature to those who hadn’t heard of it yet.

Play around with JShell yourself. You’ll need to install JDK 9. If you haven’t installed it already, go ahead and download it now.

Enhanced Navigation in Vaadin with NavigationBuilder

Developing your navigation needs in default Vaadin is ok, but I thought it could be enhanced a bit. Hence the idea of creating a new addon, NavigationBuilder.

The Idea Behind the Addon

In fact there where multiple reasons why I wanted to create some additional navigation functionality. Chaining calls to build navigation actions seemed just right. With such an approach you can achieve incredibly readable code, when properly formatted.

Besides the readability and the need to create navigation calls in a unified way, I thought that navigation actions often provide good events to trigger your own custom code. An event-handling implementation seemed suitable.

The general purpose was to make it all easier and more accessible. I also wanted to bundle refresh, back and next actions in the implementation, as they are simply navigation calls.

Builder Approach

It seemed fairly logical to apply a builder-pattern in the library. Let’s crack on with a quick example.

NavigationUtils.navigate()
                .to("www.google.com")
                .inNewTab()
                .withListener(event1 -> 
                 LOGGER.trace("Navigating to external url in a new tab."))
                .go();

With the above formatting, the chained calls are easy to read. The opening method NavigationUtils.navigate(); provides us with the Builder object from which we’ll always start. In the example above we specify an external destination url and we tell the builder that we’ll want to open the link in a new tab. After that, we attached a listener that executed our own custom code (in this case a simple log output line). Calling .go(); will build our navigation action and perform it right away. Straight forward, right?

In fact, many calls are optional and can simply be left out. The action can also be stored in a variable for later execution. That would look something like the next example.

NavigateExecutor navigation = NavigationUtils.navigate()
                .to("http://thibaulthelsmoortel.be")
                .build();
navigation.perform();

This way you can prepare all the required actions beforehand and just perform them whenever needed.

Reduced Boilerplate

At the moment of writing boilerplate code can be slightly reduced. The NavigationUtil class contains a few methods with very common navigation needs pre-configured.

Here are a few examples of how you could use those pre-built actions.

NavigationUtils.createReloadNavigation().withListener(l -> System.out.println("Page reloaded!")).go(); // Adding a listener to the pre-configured navigation.
NavigationUtils.createBackNavigation().go(); // Go back one page in the browser history
NavigationUtils.createNextNavigation().go(); // Go one page forward in the browser history

In fact, that pretty much sums it all up for now. If you have additional ideas for expanding the project, feel free to share them. I will respond to questions and feedback in comments.

If you are experiencing issues, please file them on GitHub. They will all be looked at.

The addon’s version at the time of writing is 1.1.2. Note that the addon will get updated every so often, so be aware of changes.

Interested in other Vaadin stuff? You might as well read my latest Vaadin related article about loading animations.

Managing Application Properties in Spring Boot

Many projects deal with application-wide parameters, mostly called properties. These are inputs to the program, that wouldn’t normally be changed. They do however provide for simple setup in multiple circumstances.

When to Use Properties

Good example situations in which properties would come in handy are database and email setups. If your application sends out mails, it will need to set some parameters, like protocol, host and port. If authentication is involved, properties should cover them as well. In your emailing implementation you would then read out the property values and handle them however required.

Mail properties
Some application properties for outgoing email for local development.

There are many advantages of setting these parameters in one centralized file. One of which is that quick adjustments can easily be made, without touching the code (that is, when only values are edited). When an application is deployed on multiple environments (local development, acceptance, staging, production,…) it would be enough to adjust properties in accordance with the environment on which the app is running on.

 

Reading Properties in Spring

When it comes down to extracting the values from the property file(s) when using Spring, you have a few options.

The first option, which is also the quickest solution, is to use the @Value annotation on class members or directly in an autowired constructor, as a parameters.

@Value("${my.property.name}")
private String myProperty;
@Autowired
 public MyConstructor(@Value("${my.property.name}") final String property) {
     this.property = property;
 }

Just pass your property key to the annotation. That’s it, no need to use any file reader, Spring deals with that for you. However this method is very quick and easy to implement, I’d like to point out that whenever you decide to edit the property key, you would also have to adjust it in the annotation value in code. And that would be for every annotation that reads out the edited property in question. This could obviously be made a bit more efficient and future proof.

Read Once, Access Anytime

A more solid approach would be to read all the properties (ideally when the application is launched) and put them into memory, so they would be accessible throughout the entire lifecycle of the program. Spring makes this incredibly easy, so this is by far the recommended approach.

Example class with properties in memory.
Example class with properties in memory.

In the image above, you can see an example of a class containing application properties. It contains no business logic whatsoever. The class must be annotated with Spring’s @ConfigurationProperties annotation. You can pass a prefix value (the prefix of the property key) if so required. The nested classes cover the nested properties. The protocol property in the Mail class would be the described as cs.mail.protocol in the properties file in this case. If a property key requires editing in the future, only the key and its respective property should be adjusted in code, never more, never less.

The @Data annotation (Lombok) generates all the necessary getters and setters and it reduces boilerplate code at the same time (oh, and it makes you develop that little bit faster). You could of course provide the getters and setters yourself if you don’t want to use Lombok.

Additional Spring Configuration

Not much more left to do in order to make the properties accessible in any spring component. To follow the previous example, I’d like to bring in an example Spring configuration class:

@Configuration
@EnableConfigurationProperties({ CSProperties.class })
public class PropertiesConfig {

    private final CSProperties properties;

    @Autowired public PropertiesConfig(CSProperties properties) {
        this.properties = properties;
    }

    @Bean
    public CSProperties.Database getDatabase() {
        return properties.getDb();
    }

    @Bean
    public CSProperties.Mail getMail() {
        return properties.getMail();
    }

    @Bean
    public CSProperties.Background getBackground() {
        return properties.getBackground();
    }

    @Bean
    public CSProperties.Cache getCache() {
        return properties.getCache();
    }

What this class does is simply creating beans of the property elements. It injects our base properties class in the constructor and it creates beans of the inner classes, to make them injectable anywhere. The useful aspect of this implementation is the fact that whenever you autowire one of the subclasses, you don’t get all the other properties you don’t need. Basically you just need to grab the properties that are in scope of whatever functionality you’re developing. Obviously you can also grab al the properties whenever needed.

Since our properties class is statefull and it has getters as well as setters, we are also free to change the state of the property values while running the application. This can result in totally different application behaviour, so be careful with it. Perhaps you should add some security checks for the setters access.

To wrap things of, an example extract of a database configuration class that only injects the database properties (other properties aren’t necessary here):

private final CSProperties.Database dbProps;

    @Autowired public MyBatisConfig(CSProperties.Database dbProps) {
        this.dbProps = dbProps;
    }

    @Bean
    public DataSource dataSource() {
        SimpleDriverDataSource dataSource = new SimpleDriverDataSource ();
        dataSource.setDriverClass(com.mysql.cj.jdbc.Driver.class);
        dataSource.setUrl(dbProps.getUrl());
        dataSource.setUsername(dbProps.getUsername());
        dataSource.setPassword(dbProps.getPassword());

        return dataSource;
    }

Bonus: Property Metadata

Code completion and documentation above all. Spring actually makes it possible to attach custom metadata to your properties. IntelliJ actually detects when a property key has metadata, if so, it will provide code completion and additional information. You can also define the datatypes and default values.

Property metadata file.
Property metadata file.

Have your IDE generate a JSON file in your META-INF folder. The file will be called ‘additional-spring-configuration-metadata.json’. If you decide to use such a file, make sure to update it along with the edited property file(s).

First Impressions On Vaadin

Lately I have been working a bit with Vaadin, a web UI framework for business applications. The framework offers an experience similar to Swing. ‘Similar’ is a very important word here. Vaadin uses a component based approach as well, but it is not at all a carbon copy of Swing.

Vaadin Logo

All Java

The main advantage about Vaadin is that its framework is written in Java, meaning that you could place your UI logic right next to your Java back-end logic. No need to hop from Java to Javascript or whatever other front-end programming language.

All of your UI code will run server-side. Vaadin will take care of server-client communication.

There is one small catch though. Custom styling is done in CSS (scss), so if you want to create a personalized theme, you will have to tweak around quite a bit in CSS files.

Strengths & Shortcomings

Vaadin’s biggest advantage is that you can use it to quickly create decent web application UI. You can even create your own theme fairly easily.

The framework is also struggling with some frustrating flaws. By default, Vaadin lacks the possibility to add Components to a Grid. If you want to do that anyway, you would have to install an addon. If the addon uses a widget set, it isn’t even a straight-forward installation.

Besides that I can provide a good example of an annoying flaw in Vaadin. As I was developing a Window that contained a Grid, I had the requirement to bind a boolean value to a column. The column wouldn’t just contain the boolean value as a String, but it was to be displayed as an OptionGroup with two values, ‘yes’ and ‘no’, with the correct value selected based on the boolean’s value.

The binding process went as follows: I defined a BeanItemContainer and from that I created a GeneratedPropertyContainer. On that container I performed calls of addGeneratedProperty() (for the OptionGroup I made use of a custom PropertyValueGenerator returning the OptionGroup to be displayed) . After all that I called setContainerDataSource() on the Grid. That was binding done, or at least I believed so. Once checking out the result in the UI, I noticed all cells were properly bound to their respective data, except for the OptionGroup one. Even more bizarre was the fact that at the time that a new record was added to the Grid, the data was correctly bound to all the OptionGroup cells. Somehow the Grid didn’t initialize correctly, I figured.

So it was time to find some workaround to this issue. Of course things went all smooth when using a CheckBox in stead of an OptionGroup, but that wasn’t really the requirement. Anyway, while playing around with Vaadin in some other personal project, I found out about vaadin-push. That is basically a dependency that enables you to update the UI from a different thread.

I ultimately fixed the issue by calling grid.getUI().push() right before calling grid.setColumns(). That did the trick, allthough it doesn’t look quite right.

Conclusion

I have been playing with the Vaadin framework for a few weeks now, and I’m sure I haven’t seen half of it yet. Overall I can say I’m satisfied with it, except for some frustrations that can arise on banal aspects. It is really easy to write UI fragments that are easy to read. It isn’t really hard to get into the basics. I also have to say it runs absolutely smoothly on any of my Tomcat configurations.

Overall, the framework is an excellent tool for web developers, but it is also an imperfect one. However, it is good to know that the company takes note of what developers are saying and they are always ready to help out.

If you’d like to see what Vaadin looks like, I strongly suggest you to play around with the Vaadin Sampler.

Clickable Links in Balloon Notifications – IntelliJ Plugin

The other day I took another look at my IntelliJ IDEA Plugin project, ‘Pastebin Unofficial‘ and it’s notifications. At the time of writing this project is in a very early, basic stage, it is rather an idea that hasn’t been worked properly (yet).

Clickable links in notifications

So what the project does at this time, is create a Pastebin paste from the opened document in the IDE. You right click anywhere on the opened file and you select ‘New Paste’. A popup will appear for you to specify a paste title (the filename will be picked by default). When dismissing the dialog, a paste will be sent to Pastebin and a balloon notification will be displayed for a while in the bottom right corner of the IDE.

A balloon notification with link in IntelliJ IDEA.
A balloon notification with link in IntelliJ IDEA.

The goal of the notification was to notify the user that the paste was successfully posted (a different notification would be shown when an error occurred). Only that would not be enough, no, a clickable link to this new paste would be appropriate as well.

Unfortunately, the original attempt didn’t satisfy the requirements:

final Response<String> postResult = Constants.PASTEBIN.post(paste);
NotificationGroup balloonNotifications = new NotificationGroup("Notification group", NotificationDisplayType.BALLOON, true);
    if (postResult.hasError()) {
    //Display error notification
} else {
    //Display success notification
    Notification success = balloonNotifications.createNotification("Successful Paste", "<a href=\"" + postResult.get() + "\">Paste</a> successfully posted!", NotificationType.INFORMATION, null);
    Notifications.Bus.notify(success, project);
}

In fact, it was rather naive to have used a simple html <a href="..."> tag. Even more impulsive was leaving out the required surrounding <html></html> tags.

As if those absolute failures weren’t enough, I also managed to completely ignore the latest parameter of Type NotificationListener. Passing null isn’t really going to do anything there, is it?

After a couple of Google searches I managed to find the solution. When instantiating the notification, I now include the proper surrounding tags and I provide a bit of code handling a click on the hyperlink.

This did the trick in the end:

Notification success = balloonNotifications.createNotification("<html>Successful Paste", "<a href=\"" + postResult.get() + "\" target=\"blank\">Paste</a> successfully posted!</html>", NotificationType.INFORMATION, (notification, hyperlinkEvent) -> {
    if (hyperlinkEvent.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
        BrowserUtil.browse(hyperlinkEvent.getURL());
    }
});

Now links are opening in the default browser. Note that links in the event log are now clickable as well.

However this being a valid solution, another, much cleaner one, is available as well. The final and thus preferable solution looks like this:

Notification success = balloonNotifications.createNotification(
                "<html>Successful Paste", "<a href=\"" + postResult.get() + "\" target=\"blank\">Paste</a> successfully posted!</html>",
                NotificationType.INFORMATION, new NotificationListener.UrlOpeningListener(true));

Find the original question on StackOverflow.

JToolTip Behavior Outside JFrames

As I was working on a small application, I started implementing a custom JToolTip to be used throughout the app, in stead of Swing’s default JToolTip.

The custom JToolTip entirely inside the JFrame.
The custom tooltip entirely inside the JFrame.

Testing the application I was surprised by the behavior of the tooltips when they would exceed the borders of a JFrame (exceeding for a pixel was enough).

In the image below, you can notice that a background (default Swing Color) is present for the tooltip component. This background was not present for the exact same tooltip if it appeared inside the frame. So, the goal was to remove this background.

The custom JToolTip exceeding the JFrame's border.
The custom tooltip exceeding the JFrame’s border.

First thing that came in mind was, ‘I should change the background to a transparent one’. And so I did, by calling this line on the JToolTip (mind the last parameter, the alpha value of the color):

setBackground(new Color(255, 255, 255, 0));<br />

Obviously that didn’t do the trick, but it was one step closer to the solution. In fact, someone pointed out that when the component surpasses the frame’s borders, it is actually added to a JWindow prior to being displayed.

SwingUtilities provides a method that returns the Window of a specified component:

SwingUtilities.windowForComponent(...);

It sufficed to update the background color of the window, in which the tooltip was housed, with a transparent one (alpha value of 0).

As an additional measure I made sure all the parent components of the tooltip were set to be non-opaque.

The final solution could be implemented in the overridden addNotify() method:

@Override
    public void addNotify() {
        super.addNotify();
        setOpaque(false);
        Component parent = this.getParent();
        if (parent != null) {
            if (parent instanceof JComponent) {
                JComponent jparent = (JComponent) parent;
                jparent.setOpaque(false);
            }
        }
        Window window = SwingUtilities.windowForComponent(this);
        try {
            window.setBackground(new Color(255, 255, 255, 0));
        } catch (IllegalComponentStateException e) {
            //Do nothing
        }
    }

In the above code, you may notice the catch block handling potentially raised exception: IllegalComponentStateException. It was vital to add that catch statement in. A tooltip inside a frame, not exceeding the borders, is not added to a JWindow before being displayed. This means no window background should be changed, as there would be no window.

Find the question on StackOverflow for further reference.

Track the Heap With Memory View

With Jetbrains‘ recent plugin, ‘JVM Debugger Memory View’ you can go the extra mile while debugging your applications in IntelliJ IDEA and Android Studio. If you want to keep an eye on the heap, the plugin is a valid tool to use during your debug sessions!

Memory View
A search in the Memory View.

Memory View basically lists a ton of Objects that are placed on the heap at the time present. It gives you the possibility to get a better feel of the current situation (at a breakpoint) of your application, memory-wise. The tool has packed its features inside a new tab in the IDE. You can find it by default in a panel on the right side.

In the overview you can see how many Objects have been added, removed when stepping over code. If you would place a few breakpoints you can easily view how the just executed code has affected the heap.

It is also possible to track new Instances of a particular Object. To do so you will need to turn on this feature for every class name listed.

Achievement instances in Memory View.
Achievement instances in Memory View.

Opening the class instances dialog enables filtering. Apply a filter with an evaluated expression.

Filtering in Memory View.
Filtering in Memory View.

Once you have a desired overview of instances you can unfold instances, just like you already could in the variables section in the regular debug mode. This is great for inspection of the objects. Objects where exceptions were raised properly stand out as well.

Furthermore, there is a possibility to view the call stack of the instance. When an object is selected you can view this in the stack frame on the right.

Another nice feature is the ‘Referring Objects For Object X’ one. To open up this frame, right click on an object and click ‘Show Referring Objects…’. You will now get a thorough overview of every referrer of the selected Object.

If you’ve got IntelliJ IDEA 2016.1 or higher, you can simply install the plugin from the Jetbrains repository.

As a side note I’d like to warn Android Studio users. The IDE may freeze due to a bug still present at the time of writing. Also, getting large amounts of instances could cause problems due to memory restrictions in Android. It seems the development is still ongoing. If you’ve found a bug, you can always log it in their issue tracker.

Programming Unlockable Achievements

So you wrote this game, but would now like to step up? Unlockable achievements is an aspect that enhances your game and it’s fun and interesting to program.

Minecraft Achievement
A simple Minecraft Achievement

The Concept

Let’s elaborate on the actual purpose and the concept of unlockable achievements. Basically you could consider an Achievement to be a milestone. It is a goal your end user achieves, literally. It is up to you to determine these milestones.

Let’s take Minecraft‘s ‘Taking Inventory’ achievement as an example. The achievement is unlocked at the moment the inventory is opened for the first time. This example is a single Achievement, meaning it has no predecessors or successors. Possibly you’d want to create an achievement that could only be unlocked when this one was unlocked first. You may even want to have a set of achievements unlocked before achieving a parent achievement.

The previous example was obviously very simplistic. There was one task, one goal that lead to the unlocking of the achievement. Different achievements might consist of multiple milestones to reach before unlock. Or maybe you’d want specific actions to take place in order to achieve the achievement.

Achievements Everywhere

Gaming companies, publishers and console builders all make use of achievements. Think about the trophies you can earn on PlayStation and XBox consoles. Think about achievements that you can collect on the Steam platform. And don’t forget the achievements on mobile devices in Google Play Games (Android) and Game Center (iOS). There are so many possibilities, so many things you can do with your in-game achievements. You can go beyond an implementation in your game itself.

Implementation

Let’s put things in practice by covering a possible implementation approach in Java.

You want to get things started by defining an interface:

public interface Achievable {
    void achieve();
}

Now we’re ready to define an Achievement class. You can make it Observable as we did in the following example. That way registered observers can get notified at the moment the Achievement is unlocked.

public class Achievement extends Observable implements Achievable {

    private String name, description;
    private List<AchievementProperty> propertyList;
    private boolean unlocked;

    /**
     * Class constructor specifying name, description and properties to be activated.
     *
     * @param name        the untranslated name of the achievement
     * @param description the untranslated description of the achievement
     * @param properties  the properties related to the achievement
     */
    public Achievement(String name, String description, List<AchievementProperty> properties) {
        this.name = name;
        this.description = description;
        this.propertyList = properties;
        this.unlocked = false;
    }

    /**
     * Unlocks this achievement and notifies its' observers.
     */
    @Override
    public void achieve() {
        if (!unlocked) {
            boolean allActive = true;
            for (AchievementProperty property : propertyList) {
                if (!property.isActive()) {
                    allActive = false;
                    break;
                }
            }
            if (allActive) {
                this.unlocked = true;
                setChanged();
                notifyObservers();
            }
    }
//Getters, setters and toString omitted...
}

As you can see in the above code, the achievement contains a list of AchievementProperty. These are properties that need to be active when the achievement is unlocked.

Here’s how the AchievementProperty class may look like:

public class AchievementProperty {

    private String name;
    private int value;
    private String activation;
    private int activationValue;
    private int initialValue;
    private String tag;

    /**
     * Class constructor specifying name, activation, activation value and initial value.
     *
     * @param name            the untranslated name of the property
     * @param activation      the activation method of the property
     * @param activationValue the activation value of the property
     * @param initialValue    the initial value of the property
     */
    public AchievementProperty(String name, String activation, int activationValue, int initialValue) {
        this.name = name;
        this.activation = activation;
        this.activationValue = activationValue;
        this.initialValue = initialValue;
    }

    /**
     * Class constructor specifying name, activation, activation value, initial value and tag.
     *
     * @param name            the untranslated name of the property
     * @param activation      the activation method of the property
     * @param activationValue the activation value of the property
     * @param initialValue    the initial value of the property
     * @param tag             the tag of the property
     */
    public AchievementProperty(String name, String activation, int activationValue, int initialValue, String tag) {
        this.name = name;
        this.activation = activation;
        this.activationValue = activationValue;
        this.initialValue = initialValue;
        this.tag = tag;
    }

    /**
     * Returns true when this property is active, false if otherwise.
     *
     * @return true when this property is active, false if otherwise
     */
    public boolean isActive() {
        boolean flag = false;

        switch (activation) {
            case Achiever.ACTIVE_IF_GREATER_THAN:
                flag = value > activationValue;
                break;
            case Achiever.ACTIVE_IF_LESS_THAN:
                flag = value < activationValue;
                break;
            case Achiever.ACTIVE_IF_EQUALS_TO:
                flag = value == activationValue;
        }

        return flag;
    }

    /**
     * Resets this property's current value.
     */
    public void reset() {
        this.value = initialValue;
    }

Now it’s up to you to get all that linked up by creating the ‘Achiever’ class. I’ll leave that as an exercise to the reader. Here’s a bit more context to get you going:

  1. Make use of a HashMap to keep AchievementProperty instances;
  2. Make use of a HashMap to keep Achievement instances;
  3. Provide a ‘defineProperty’ method that creates and returns a new AchievementProperty based on specified parameters. If the property is not yet listed in the HashMap, put it in there;
  4. Provide a ‘defineAchievement’ method that creates and returns a new Achievement based on specified parameters (do not forget its’ related Achievementproperty/AchievementProperties!). If the achievement is not yet listed in the HashMap, put in in there;
  5. Add a method that will achieve all eligible achievements (don’t forget checks on the related AchievementProperty/AchievementProperties;
  6. Add methods to add/set a value to properties, or even to reset property values.

At this point you can create your new achievements and their respective related property/properties.

On the moment a property needs to get an update, you call the ‘addValue’ method from step 6 and you call the ‘checkAchievements’ method from step 5. This way your achievements can get unlocked at the proper time.

About the Bromine Project

Since my experience with Selenium is growing I become to understand it better every day. At first I was amazed about its possibilities. You can do a lot with Selenium WebDriver, but soon enough I came to realize it’s missing a few aspects. That’s how Bromine evolved from idea to project.

Filling in the Gaps

The Bromine project’s aim is to fill in the gaps in the default Selenium WebDriver Livery for Java. In stead of using Selenium, use Bromine that will on its turn use Selenium for you, while still leaving you enough means of customizing the WebDriver functionality.

Screenshots

A good example of a feature I was really missing in Selenium was a descent way of taking screenshots. The method getScreenshotAs(OutputType.FILE); just simply didn’t quit fulfill my needs (and those were from an automatic testing’s perspective). What I specifically wanted to be able to take a screenshot of the current browser instance any time I’d desire, but more importantly, every time a unit test fails.

An example screenshot taken by a Bromine command.
An example screenshot taken by a Bromine command.

In Bromine, a simple JUnit rule can take care of just that. Add it to your test class as follows:

@Rule
public ScreenShotOnFailure failure = new ScreenShotOnFailure("./screenshots/");

Statistics

When I use Selenium in a test framework, at some point, I might become interested in several statistics. Of course I do not intend to re-invent the wheel. I respect the current web analytics standard of today, Google Analytics, and I believe it to cover most needs one can have regarding statistics and analysis of a website.

What Google Analytics doesn’t provide you is statistics of events on your web page right in your test framework.

Why would that even be useful? Well, if you’re creating an automated test framework you are trying to ensure a qualitative final product for your users to interact with. Wouldn’t you want to know how many clicks one has to perform before reaching a particular page? Aren’t you interested in how many times form fields have to be filled in before a desired action occurs? Those are examples of what Bromine would like to cover.

As of version 0.2-alpha, a basic implementation of this is in place, ready for you to extend at will. I made sure I provided at least a very minimum, being tracking of left mouse button clicks, double clicks and the amount of times keys are entered.

Since I can image one might find the need to create their own tracking means, I ensured the system works with plugins (StatsPlugin) that can be registered and enabled any time.

Bringing SUT Structure

Selenium merely provides the ability to browse through websites, while what many might want to do would be structuring their System Under Test (SUT) inside their framework. It is a good practice to do so, since you might want to reuse pages and features that are used across the site multiple times.

Bromine provides a base to register pages (Page) and their respective sections (section) to a globally accessible collection (Pages). The easiest way to implement your application structure would be to assign a specific package in your project to contain classes extending the Page class. If you make use of the default no-parameter constructor, you won’t even have to create new instances of your pages. Just make sure to call registerAllPagesFromPackage(String pack) from the Pages class to register all your predefined pages to the collection.

Work in Progress

Bromine is currently in a very early stage. Additional extensions to Selenium are more than likely to appear, as well as probable breaking changes in the future. Needless to say that Bromine has to evolve as does Selenium.

Personally, I attempt to use the framework in multiple different projects. That way I can evaluate how useful it is and how well it works. Most useful features at the moment (for me personnally) are the screenshots and the structuring of pages from the SUT.

I’m happy to share the source on GitHub. I made it to be open source since I will always be open to feedback and improvement suggestions.