2015-08-16

All field constructor in Groovy

TupleConstructor annotation in Groovy generate constructors for class with each of its properties (eventually also fields). The class below

@TupleConstructor(includeFields = true)
class Person {
   String firstName
   String lastName
   private boolean male
}

will have constructors: Person(), Persion(String), Person(String, String) and Person(String, String, boolean). You could test it using code below.

class TupleConstructorTest extends GroovyTestCase{
    @Test
    void testSimpleTupleConstructorShouldGenerateConstructor() {
        assertScript '''
            import groovy.transform.TupleConstructor
            @TupleConstructor(includeFields = true)
            class Person {
                private final String firstName
                private final String lastName
                private final boolean male
                String toString(){ "$firstName $lastName $male" }
            }

            assert Person.constructors.size() == 4

            assert new Person().toString() == 'null null false'
            assert new Person('John').toString() == 'John null false'
            assert new Person('John','Smith').toString() == 'John Smith false'
            assert new Person('John','Smith', true).toString() == 'John Smith true'
        '''
    }
}

I almost always create classes with all private final fields and generate constructior with all fields using my IDE.

So I have prepared new transformation AllFieldConstructor which bases on TupleConstructor and generates only constructor with all fields as parameters.

class AllFieldConstructorTest extends GroovyTestCase{
    @Test
    void testSimpleTupleConstructorShouldGenerateConstructor() {
        assertScript '''
            import com.blogspot.przybyszd.transformations.AllFieldConstructor
            @AllFieldConstructor
            class Person {
                private final String firstName
                private final String lastName
                private final boolean male
                String toString(){ "$firstName $lastName $male" }
            }

            assert Person.constructors.size() == 1

            assert new Person('John','Smith', true).toString() == 'John Smith true'
        '''
    }
}

The sources are available here

2015-06-04

Git aliases for better Gerrit usage

What is Gerrit?

Gerrit is a web application for code review and git project management. You push commit to specific ref in Gerrit and your collaborators could comment your code, give you a score (-2, -1, 0, 1, 2) or merge it with specific branch. Gerrit generates also events, so yout CI server (for example Jenkins) could start build based on this commit and give the positive score if build is green or negative if it fails.

Pushing commits to gerrit

If you want to push commit to gerrit, then commit has to have generated Change-Id, which is uniq review identifier. You do not need to generate Change-Id on your own, because you could install pre-commit hook from Gerrit:

gitdir=$(git rev-parse --git-dir); scp -p -P <GERRIT_PORT> <GERRIT_SSH>:hooks/commit-msg ${gitdir}/hooks/

Of course, you have to set GERRIT_PORT and GERRIT_SSH to point to yout Gerrit.

To push a commit for review you should use command:

git push origin HEAD:refs/for/<BRANCH_NAME>

It means that your current HEAD should be pushed to remote reference on origin (if Gerrit remote repository is named as origin). BRANCH_NAME is the remote branch with which your code will be compared and to which your commit should be merged (if it pass review).

You often push to master so there is alias to push as review for master in alias section in ~/.gitconfig (globally) or .git/config (only in current repository):

[alias]
  ...
  push-for-review = push origin HEAD:refs/for/master
  ...

To execute it just type:

git push-for-review

If I want to push as review to another branch then I use another alias:

[alias]
  ...
  push-for-review-branch = !git push origin HEAD:refs/for/$1
  ...

and branch name could be pass as argument from command line:

git push-for-review-branch <BRANCH_NAME>

Pushing drafts

If you think that your commit is not ready to merge with remote branch, but you want to share it or just have it in remote repository, you could push it to draft reference. Draft on gerrit is available only for you and other users which are invited by you. Draft could be pushed via command:

git push origin HEAD:refs/drafts/<BRANCH_NAME>

Branch name must be given, because draft could be published and then merged, so branch have to be known before.

There also are simple aliases, which could be used in the same way as during push for review:

[alias]
  ...
  push-as-draft = push origin HEAD:refs/drafts/master
  push-as-draft-branch = !git push origin HEAD:refs/drafts/$1
  ...

Invite for review

After pushing for review or draft you could invite user or group, then they will be notified by Gerrit about new change. To invite from command line there should be added four aliases:

[alias]
  ...
  gerrit-remote = "!sh -c \"git remote -v | grep push | grep ssh | grep gerrit | head -1 | awk '{print $2}' | cut -d'/' -f3\""
  gerrit-host = "!sh -c \"git gerrit-remote | cut -d':' -f1\""
  gerrit-port = "!sh -c \"git gerrit-remote | cut -d':' -f2\""
  gerrit-invite = "!sh -c \"ssh -p `git gerrit-port` `git gerrit-host` 'gerrit set-reviewers --add' $1 `git log | grep Change-Id | head -1 | tr -d ' ' | cut -d':' -f2`\""
  ...

First alias selects remote repository which contains gerrit in name or url, could be used to push via ssh and extracts url to this repository.

Second and third alias uses the first to extract host and port from repository url. It is necessary for executing remote command via ssh.

The last alias extract Change-Id from HEAD and add user or group given form command line. Example usage:

git gerrit-invite <USER_OR_GROUP> 

Summary

Gerrit is a great tool for git management and code reviewing, but it is difficult to type all references by memory. Git aliases described here are great support and simplify Gerrit usage.

2015-03-29

All you need is docker (and fig)

Introduction

Suppose you want to run scala repl or groovy shell or any other repl-like executable. You should download executable, unpack it, set PATH environmnt variable and now you could use it. Can it be simple? Yes, dockerize everything.

Prepare containers

I expect that you have installed docker and fig on your machine.
Checkout this project from github and build containers:

$ cd docker-with-fig
$ fig build 

It could take several minutes, depends on your internet connection.

You could also build only some of available container, for example with scala and groovy:
$ fig build scala groovy

Available containers are:
  • haskell
  • scala
  • groovy
  • python27
  • python34
  • clojure

Run containers

Now you could start for example scala:
$ fig run scala
Welcome to Scala version 2.11.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_40).
Type in expressions to have them evaluated.
Type :help for more information.

scala>

Or groovy:
$ fig run groovy
Mar 29, 2015 7:48:22 AM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
Groovy Shell (2.4.2, JVM: 1.8.0_40)
Type ':help' or ':h' for help.
-------------------------------------------------------------------------------
groovy:000>

Or clojure with lein:
$ fig run clojure
nREPL server started on port 52730 on host 127.0.0.1 - nrepl://127.0.0.1:52730
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_40-b25
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=>

Or python 3.4:
$ fig run python34
Python 3.4.2 (default, Oct  8 2014, 13:08:17) 
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

Or ghci haskell:
$fig run haskell
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude>

You could also run command on docker container with use of files from your current directory because it is mapped to /project directory on docker. Container starts with /project directory as current directory.
For example you have a simple file in your current dir:
$ cat simplePrint.scala 
println("Hello World")

You could run command with this file:

$ fig -f PATH_TO_DOCKER_WITH_FIG_PROJECT/fig.yml run scala scala simplePrint.scala
Hello World

First 'scala' in command means that you want to run scala container and 'scala simplePrint.scala' means that you want to execute this command on container.

Conclusion

It is simple, isn't it? All you need is docker and fig and you could use repl or run command with scala, groovy, cojure and any other which are currently supported...

2014-06-21

Sorting photos after holiday

Introduction

When my wife an I are on vacation, we always take photos using two cameras. One is my own and second belongs to my wife. After holidays we want to have one folder with all the photos sorted by date and time and named in this manner, so we do not have to select sort_by_date each time we want to view them. Of course, date and time on our cameras are synchronized.

Main

Creation date and time could be obtain from photo file using exiftool program from command line:
$ exiftool DSCN6201.JPG
and the output looks like this:
ExifTool Version Number         : 9.13
File Name                       : DSCN6201.JPG
Directory                       : .
File Size                       : 2.8 MB
...
Date/Time Original              : 2013:08:15 08:56:34
Create Date                     : 2013:08:15 08:56:34
...
I have written shell script which using exiftool rename all JPG files in current directory with prefix_yyyy_mm_dd__hh_mm_ss.JPG pattern. I only have to copy script file to photo directory and execute it with given prefix:
$ ls
DSCN6201.JPG  DSCN6203.JPG  DSCN8338.JPG  DSCN8340.JPG
DSCN6202.JPG  DSCN8337.JPG  DSCN8339.JPG  sorter.sh
$ ./sorter.sh holidays
$ ls
holidays_2013_08_15__08_55_55.JPG  holidays_2013_08_15__08_56_34.JPG
holidays_2013_08_15__08_56_08.JPG  holidays_2013_08_17__08_37_44.JPG
holidays_2013_08_15__08_56_22.JPG  holidays_2013_08_17__08_41_55.JPG
holidays_2013_08_15__08_56_29.JPG  sorter.sh
Script is available here.

Conclusion

Simple shell script can rename all your photos based on their creation date and time.

2014-05-25

Convert html page to mobi

Introduction

Sometimes I want to read webpage on my kindle. There are many pictures and source code blocks on this. What can you do? You can print webpage as pdf, but this is not good idea, because you cannot scale such document on kindle. Mobi is better file format so there must be better option and indeed is.

Kindlegen

Amazon provides little program called kindlegen, which could convert html, epub and some other formats to another and there is mobi. You have to save webpage with all css files and images somewhere on your disk. You could do this for example with Google Chrome, just push CTRL+S and select place. Now you should have html file and directory name like your html file without extension, but with _files suffix. For example I have download this webpage on my desktop and I have file Przybysz Dominik TechBlog.html and Przybysz Dominik TechBlog_files directory.
To use kindlegen you need all css and image files placed in the same directory as html file, so all local links from html files have to have deleted prefix describing directory. For example I have deleted ./Przybysz Dominik TechBlog_files/ from all src atributtes and moved html file to directory with other files.
Now you could use kindlegen:
kindlegen Przybysz\ Dominik\ TechBlog.html -o blog.mobi
Now your mobi file is ready to be placed on you kindle.

Conclusion

With one simple program you could convert any webpage to mobi format and read it on your kindle.

2014-05-17

Guice Tutorial - 09 - Providers in modules

Introduction

Module in Guice is not only a place where binding are defined. It also could have definition of many providers inside.


Provides

Suppose we have quiz class which has to be initialized before usage by call of method init.
public class Quiz {
    private boolean initialized = false;

    public boolean initialized(){
        return initialized;
    }

    public void init(){
        initialized = true;
    }
}
Provider is quite simple, because it only creates Quiz object and call method init, so we define it inside module.
public class QuizModule extends AbstractModule {
    @Override
    protected void configure() {}

    @Provides
    private Quiz getinitializedQuiz(){
        Quiz quiz = new Quiz();
        quiz.init();
        return quiz;
    }
}
Provides annotation tells Guice that annotated method is provider for its return type. Provider could be defined in this manner only in module.
Let's test it:
@Test
public void shouldClassInstanceFromProvider(){
    //given
    Injector sut = Guice.createInjector(new QuizModule());
    //when
    Quiz quiz = sut.getInstance(Quiz.class);
    //then
    assertTrue(quiz.initialized());
}

Conclusion

If you have to define provider, but you do not want to have separete provider class, than you could create method which acts like provider in your module. Sources are available here.

2014-05-10

Guice Tutorial - 08 - Combine modules

Introduction

Single injector could be created from many modules, so dependecies could be separeted depends on their domain.


Combining modules

Suppose you have two modules. One describes classes using to talk with database and second provides classes for frontend. For database there are SessionFactory interface with its implementation - SessionFactoryImpl. The bining is defined in DatabaseModule.
public interface SessionFactory {}
public class SessionFactoryImpl implements SessionFactory {}
public class DatabaseModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(SessionFactory.class).to(SessionFactoryImpl.class);
    }
}
Widget interface is bound to LabelWidget iFrontendModule .
public interface Widget {}
public class LabelWidget implements Widget{}
public class FrontendModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(Widget.class).to(LabelWidget.class);
    }
}
We want to have injector, which uses this two modules, so we could create it in this way:
@Test
public void shouldJoinTwoDisjointModules(){
    //when
    Injector sut = Guice.createInjector(new DatabaseModule(), new FrontendModule());
    //then
    assertNotNull(sut.getInstance(SessionFactory.class));
    assertNotNull(sut.getInstance(Widget.class));
}
One constraint is that combined modules cannot have bindings for the same classes or interfaces.


Overriding modules

Suppose you have TestSessionFactoryImpl that you want to use in your tests.
public class TestSessionFactoryImpl implements SessionFactory{}
Binding for tests is defined in TestDatabaseModule.
public class TestDatabaseModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(SessionFactory.class).to(TestSessionFactoryImpl.class);
    }
}
Tring to combine this module with your DatabaseModule ends with CreationException.
@Test(expected = CreationException.class)
public void shouldThrowExceptionWhenJoiningTwoModulesWithTheSameBindings(){
    Guice.createInjector(new DatabaseModule(), new TestDatabaseModule());
}
To not obtain CreationException you should tell Guice that you want to override bindings of DatabaseModule with your TestDatabaseModule.
@Test
public void shouldOverrideModule(){
    //when
    Injector sut = Guice.createInjector(Modules.override(new DatabaseModule()).with(new TestDatabaseModule()));
    //then
    assertEquals(TestSessionFactoryImpl.class, sut.getInstance(SessionFactory.class).getClass());
}

Conclusion

You can combine many modules during creation of injector, but only if they have no bindings for the same classes. If they have, you have to explicitly tell Guice which module overrides bindings in another module. Sources are available here.

2014-05-01

Guice Tutorial - 07 - Module

Introduction

So far, we was using only annotations and creating injector without giving any parameters. It could be possible, because we was using classes defined by us or having no-arg constructor. But sometimes we have to use classes from external library, which do not meet these conditions. With the help comes to us Module.

Module

The module is an interface which has only one method - configure, where bindings could be defined. Binding is a form, which tells injector how to obtain instance of class that we ask for. It looks like this: bind(class).toSth(...). The best way to have defined bind method in your module is extend AbstractModule class.
public class MyModule extends AbstractModule{
    @Override
    protected void configure() {
        //...
    }
}
Module is the main definition for injector and when something is undefined then it also use bindings defined via annotations. Important is that module always overrides annotations, for example when class has annotations and module defines binding for it, then module binding is used.

Binding to constructor

First binding tells how to obtain class using constructor and there is method toConstructor where you could pass a constructor:
try {
    bind(FirstClass.class).toConstructor(FirstClass.class.getConstructor(Dependency.class));
} catch(NoSuchMethodException e) {
    // But i know it exists
    e.printStackTrace();
}
FirstClass class (and almost all class used in examples) looks like this:
public class FirstClass {
    private Dependency dependency;

    public FirstClass(final Dependency dependency) {
        this.dependency = dependency;
    }
}
It is not so easy to define constructor in this way so if I could I use Inject annotation, which means the same.
public class SecondClass {
    private Dependency dependency;

    @Inject
    public SecondClass(final Dependency dependency) {
        this.dependency = dependency;
    }
}

Binding to provider

We are using Provider to prepare class and module changes nothing, but we could replace ProvidedBy annotation in class with toProvider method in module:
bind(ThirdClass.class).toProvider(ThirdClassProvider.class);

Binding to instance

Of course, you could create one instance of class and want to pass it to every class, which could use it. We bind it using toInstance.
bind(FourthClass.class).toInstance(new FourthClass(new Dependency()));

Binding to concrete implementation

When we want to inject concrete implementation for interface or abstract class we have been using ImplementedBy annotation. In module we could simply use to and tell which class we want to bind to it. Of course, we have to define how to obtain this class (in module or via annotations).
bind(SomeClass.class).to(FifthClass.class);

Using scope

We could define that we want the class to be the singleton via annotation Singleton, so in module we should have this possibility too. And we have. We could tell in which scope class should be using method in at the end of each binding. For example:
try {
    bind(SixthClass.class).toConstructor(SixthClass.class.getConstructor(Dependency.class)).in(Singleton.class);
} catch(NoSuchMethodException e) {
    e.printStackTrace();
}

Conclusion

Annotations and module could be used to describe how injector should create instances of classes that we ask for. But annotations could be placed only on our classes, while module could describe creation for each class and is more important for Injector than annotations. 
All sources are available here.

2014-04-27

Guice Tutorial - 06 - Injecting injector

Introduction

Suppose you need a factory which gives you one implementation of interface depends on given parameter. The number of possible implementations is quite big. It could be resolved with factory with injected providers of each implementation, but in Guice we have a better way to achieve this goal...

Main

We could inject Injector to our class. We have a builder factory which could gives us implementation based on parameter:
public class BuilderFactory {
    private Injector injector;

    @Inject
    public BuilderFactory(final Injector injector) {
        this.injector = injector;
    }

    public Builder getBuilder(String param){
    if("first".equals(param)){
        return injector.getInstance(FirstBuilder.class);
        } else if("second".equals(param)){
            return injector.getInstance(SecondBuilder.class);
        } else {
            return injector.getInstance(DefaultBuilder.class);
        }
    }
}
And there are builders:
public interface Builder {}
public class FirstBuilder implements Builder{}
public class SecondBuilder implements Builder{}
public class DefaultBuilder implements Builder{}

First, to test is simply get injector from injector:
@Test
public void shouldInjectInjectorFromInjector(){
    //given
    Injector sut = Guice.createInjector();
    //when
    Injector result = sut.getInstance(Injector.class);
    //then
    assertEquals(sut, result);
}

Now let's get specific builder from our BuilderFactory:
@Test
public void shouldGetFirstBuilderFromFactory(){
    //given
    Injector sut = Guice.createInjector();
    BuilderFactory builderFactory = sut.getInstance(BuilderFactory.class);
    //when
    Builder builder = builderFactory.getBuilder("first");
    //then
    assertTrue(builder instanceof FirstBuilder);
}

@Test
public void shouldGetSecondBuilderFromFactory(){
    //given
    Injector sut = Guice.createInjector();
    BuilderFactory builderFactory = sut.getInstance(BuilderFactory.class);
    //when
    Builder builder = builderFactory.getBuilder("second");
    //then
    assertTrue(builder instanceof SecondBuilder);
}

@Test
public void shouldGetDefaultBuilderFromFactory(){
    //given
    Injector sut = Guice.createInjector();
    BuilderFactory builderFactory = sut.getInstance(BuilderFactory.class);
    //when
    Builder builder = builderFactory.getBuilder("unknown");
    //then
    assertTrue(builder instanceof DefaultBuilder);
}
And every tests pass.

Conclusion

When we have to create factory which gives us many concrete implementation we could inject injector to factory to not inject many providers of this concrete implementations. Source code is available here.

2014-04-20

Guice Tutorial - 05 - Default interface implementation

Introduction

Sometimes we have to define interface and write only one class which implements it, for example we see possibility of extending in future or we want to make our class final to prohibit making subclasses of this type or maybe we want to have one default implementation of interface. This goal could be obtained with Guice.


Interface and class

We have class:
public class PdfReportWriter implements ReportWriter{
    @Override
    public void write() {
        // ...
    }
}
which implements our interface and it is only class which do this. Interface looks so:
@ImplementedBy(PdfReportWriter.class)
public interface ReportWriter {
    void write();
}
By the ImplementedBy annotation we say to Guice that if I ask for object of type ReportWriter than we should by default obtain object of type PdfReportWriter. Let's test it:
@Test
public void shouldGetImplementationOfInterface(){
    //given
    Injector sut = Guice.createInjector();
    //when
    ReportWriter reportWriter = sut.getInstance(ReportWriter.class);
    //then
    assertTrue(reportWriter instanceof PdfReportWriter);
}
And the test passes.


Conclusion

When we have interface which has only one implementation or we want to make this class default implementation for interface than we could use ImplementedBy annotation in Guice. Sources are available here.