Lightweight JIRA integration in IntelliJ IDEA

Topic of this post is a setup of simple JIRA integration in IntelliJ IDEA without Atlassian Plugin. Principals can be applied to any similar applications, like YouTrack. Plugins might provide extensive functionality for ticket management, but I find web application in browser good enough for that purpose and don't want to clutter my IDE with too much functionality. It is nice however to be able to jump to the current task description, or quickly navigate to tasks referenced in commit messages.

Pick a current ticket as a task

JIRA tickets can be shown as tasks. For start, open a task with a shortcut "Shift+Alt+N".

Clicking on settings icon will open task settings where new server can be added. Click plus (+), select JIRA and fill in the details:
Default search options will show only tasks assigned to you.
Take a note there is a commit message tab that you can customize to match your projects standards, it defaults to a common one: {id} {summary}
Now you can open task "Shift+Alt+N", pick one, and you will be presented with the dialog. Here I like to pick "Create Changelist" so all your changes for this task go into this changelist. There is possibility to create branch and change ticket status, but that can be done in respective tools(If you don't switch tickets that often).
When task is selected, you can open it in a browser at any time with shortcut "Alt+Shift+B".

Click on a ticket number in commit message

There is a beautiful feature of Version Control panel that can turn ticket numbers in commit messages and changelist names into links that open JIRA ticket in browser. It can be setup in Settings->Version Control->Issue Navigation. Here you add a new line where Issue ID is regular expression that should recognize ticket number. For example, ticket DATACMNS-975 can be covered with
[A-Z]+\-\d+
Expression can probably be improved, but this one is fine as well. Link should be issue URL with a placeholder for a ticket number. If link example is "https://jira.spring.io/browse/DATACMNS-975", then template would be:
https://jira.spring.io/browse/$0
After saving, look at the history of a project or a file. You should be able to click on a ticket number in commit messages in order to open them in a browser.

DDD and REST in Spring Part 1: Id serialization

DDD (domain driven design) is a design technique that helps to manage complexity by using object oriented design and language and principals of the domain(what is being implemented). I highly recommend the book on the topic: Implementing Domain-Driven Design by Vaughn Vernon, even though book is offering a lot of good advice, one should be careful of which ones to pick.
I stumbled upon a problem in a low level design trying to use some of the principles in an application that is exposed via REST interface. Using Spring and Hibernate (and JPA) it is possible to deserialize a json document directly in JPA Entity and store it. Note: I always suggest pragmatic approach, if entity(or surrounding logic) is simple I use entity directly, if it gets more complex I refactor the code to use some sort of DTO. 
So for example a simple entity:

package com.magdicgoran.molecule;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Molecule {

    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private String formula;


    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getFormula() {
        return formula;
    }
}

And rest API:
GET molecules - returns all molecules
GET molecules/{id} - returns one molecule by id
POST molecules - adds a new one
PUT molecules/{id} - updates molecule with id
DELETE molecules/{id} - deletes molecule with id
Implementation for POST method:

@RequestMapping(path = "molecules", method = POST)
@ResponseStatus(HttpStatus.CREATE)
public Molecule add(@RequestBody Molecule molecule) {
    return moleculeRepository.save(molecule);
}

where moleculeRepository is just:

public interface MoleculeRepository extends CrudRepository {
}

It looks nice and simple, but has a bug. Since it is a rest interface, user can send any json:

{
    "id": 1,
    "name": "water"
}

And instead of adding a new entry, code above will update the entry with id 1. Why? Jackson, the library used for json serialization is setup by spring boot to discover fields in classes using getters and setters (id has a getter), and once it discovers them it will be able to set them (even though it discovered just getter) unless you tell it otherwise using annotations. Spring data repository save method will add new if there is no id, and update if there is an id. We can add @JsonIgnore, but that will prevent serialization as well. So to prevent deserialization only, we can use something like this:

@Id
@GeneratedValue
@JsonIgnore
private Long id;

@JsonProperty
public Long getId() {
    return id;
}

That looks good, in all the interfaces above, id does not need to be set in entity, POST method has it in the URL. It seems to be a common mistake in different tutorials, POST methods with ids in both URL-s and deserialized entities. Authors use the one from the entity, so you can write whatever you want in the URL of the request and still update the entity identified by the id in the body of the request.The code above allows only ids in the URLs to be set.
After that, I stumbled upon a bit harder problem. What if this entity is just a part of the aggregate (another entity), and you need to reference it? Whatever JSON you post, this entity will end up without id and new one will be added if you just save aggregate. I will address that in the next post

Reading file in reverse order using commons.io and streams

Let's say you want to read file from the end. There are a few implementations you can use, org.apache.commons.io.input.ReversedLinesFileReader for example or you cold find alternative one somewhere on the google. There is nice post on Crunchify covering the topic. Both of the examples have readLine method but it is not easy to use them in Java 8 streams since they don't implement method like java.io.BufferedReader.lines. To use them with streams anyway we need to create Spliterator and them simple StreamSupport.stream will create desired stream.

@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();

@Test
public void reversedLinesReader_canBeUsedWithStreams() throws IOException {
  File file = temporaryFolder.newFile("testFile.txt");
  Files.write(file.toPath(), Arrays.asList("line1", "line2", "line3", "line4"));

  try (ReversedLinesFileReader reader = 
               new ReversedLinesFileReader(file, defaultCharset())) {
      Iterable<String> iterable = () -> new IOSupplierIterator<>(reader::readLine);
      List<String> lines = StreamSupport.stream(iterable.spliterator(), false)
              .limit(3).collect(Collectors.toList());
      assertThat(lines).isEqualTo(Arrays.asList("line4", "line3", "line2"));
  }
}
SupplierIterator from my previous post has to be altered in order to work with the method reference as above(reader::readLine), because method throws checked IOException. To use an existing one, above code would need to be altered to use lambda instead of a method reference and have try-catch block that would handle IOException. That responsibility can be given to an iterator:

public class
IOSupplierIterator<T> implements Iterator<T> {
    private T buffer = null;
    private IOSupplier<T> supplier;

    public IOSupplierIterator(IOSupplier<T> supplier) {
        this.supplier = supplier;
    }

    @Override
    public boolean hasNext() {
        return (buffer != null) ||
                (buffer = supplierGet()) != null;
    }

    private T supplierGet() {
        try {
            return supplier.get();
        } catch (IOException e) {
            throw new UncheckedIOException(e.getMessage(), e);
        }
    }

    @Override
    public T next() {
        if (hasNext()) {
            T next = buffer;
            buffer = null;
            return next;
        } else {
            throw new NoSuchElementException();
        }
    }

    @FunctionalInterface
    interface IOSupplier<T>{
        T get() throws IOException;
    }
}
Note: Assert used in the test comes from AssertJ library that I recommend.

Iterator from Supplier

Creating an Iterator can be one step towards creating a stream from some resource. SupplierIterator takes only a Supplier and uses buffer for the next value. Example is inspired by java.io.BufferedReader.lines() method.

public class SupplierIterator<T> implements Iterator<T> {
   private T buffer = null;
   private Supplier<T> supplier;

   public SupplierIterator(Supplier<T> supplier) {
      this.supplier = supplier;
   }

   @Override
   public boolean hasNext() {
      return (buffer != null) ||
         (buffer = supplier.get()) != null;
   }

   @Override
   public T next() {
      if (hasNext()) {
         T next = buffer;
         buffer = null;
         return next;
      } else {
         throw new NoSuchElementException();
      }
   }
}

Get Stream from Iterator

If you have a class implementing Iterable, you can get a Stream over elements just by:
StreamSupport.stream(iterable.spliterator(), false);
 If the class doesn't already have a stream method. But if you only have an iterator and still want to use streams, you can use the fact that Iterable is a functional interface since it has only one non-default method, so if you already have an iterator, you can create Iterable by:
Iterable<String> iterable = () -> iterator;
It returns always the same iterator, so it is more a hack then a solution, but approach can be used by one of those classes that can produce iterator but are not implementing Iterable interface.
Iterable<String> iterable = () -> legacyClass.iterator();
return StreamSupport.stream(iterable.spliterator(), false);