Python rstrip in Java

by GarciaPL on Friday 13 July 2018

Last time I was working on migration of some code from Python into Java and I was trying to find a corresponding code in Java for a function called rstrip in Python. So, below you can see a code written in Python and solution written in Java produced of course using Guava.

icb_code.rstrip("0")


CharMatcher trailingZeroMatcher = CharMatcher.is('0');
String trimmedInput = trailingZeroMatcher.trimTrailingFrom(input);

Case Insensitive Map in Java

by GarciaPL on Wednesday 11 July 2018

I needed recently to create a case-insensitive map in Java to query it with keys which might be uppercase or lowercase. I thought that it should be somewhere some kind of solution already available for developers. I found a class called CaseInsensitiveMap in Apache Commons Collections package (https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/map/CaseInsensitiveMap.html) but unfortunately, I found later on that it does not support generics which was needed in my case, that's why I decided to go with a custom solution for that problem which might be found below.

Map<String, String> record = getRecord();

TreeMap<String, String> caseInsensitiveMap = new TreeMap<>getCaseInsensitiveComparator());

caseInsensitiveMap.putAll(record);

protected Comparator<String> getCaseInsensitiveComparator() {
    return Comparator.nullsFirst(String.CASE_INSENSITIVE_ORDER);
}

Splitting list by enum property to get map of enum and list

by GarciaPL on Sunday 1 July 2018

Last time I had a problem with how to split the incoming list of a type File, to get a map of list of files by FileType, which is a property of File class. The easiest way to achieve it? Reduce.

Input -> List<File> listOfFiles
Output -> Map<FileType, List<File>>

public Map<FileType, List<File>> splitFilesByFileType(List<File> listOfFiles) {
    return listOfFiles.stream()
        .reduce(new HashMap<>(), (filesByFileType, file) -> {
            FileType fileType = file.getFileType();
            if (filesByFileType.containsKey(fileType)) {
                filesByFileType.get(fileType).add(file);
            }
            else {
                filesByFileType.putIfAbsent(fileType, Lists.newArrayList(file));
            }

            return filesByFileType;
        }, (acc1, acc2) ->
        {
            acc1.putAll(acc2);
            return acc1;
        });
}

IntelliJ IDEA - Ticket around new feature

by GarciaPL on Sunday 13 May 2018

Last time I was thinking about one small feature which might be added into IntelliJ IDEA, that's why I created a task on their ticketing system, so hopefully, all of us might use it one day in the future.

It's just an idea of a new feature which is basically an additional safety check. So, when a developer runs SQL script in IntelliJ IDEA like 'DELETE FROM tableName', it might show up confirmation if a developer is really sure about dropping data from a database. This dialog box might show up eventually the amount of data to be deleted and environment which is going to be affected. I hope that this feature might save a lot of developer's lives.

Link to ticket https://youtrack.jetbrains.com/issue/DBE-6408

Enum helper method - avoid equals

by GarciaPL on Friday 13 April 2018

Do you still write those special if statements for enums like myEnum.equals(myEnum.TEST) ? If yes, I might be able to share with you a small tip how to avoid it! It will be very beneficial for you because of your code might express itself without a word! Moreover, you might avoid those imports of your enum fields in every class where the comparison is going to be defined by if statement. It will say you a lot of time in case of changing name of enum field.

For instance, for the example defined below, only what you need to do in your code is -> if (operation.isCount()) {...} instead of if (operations.equals(Operation.COUNTA)) {...}

Check this post on Medium.com -> Use enum utility methods in Java ! Avoid equals at all costs!

import org.apache.commons.lang3.EnumUtils;

public enum Operation {

    COUNTA,
    SUM,
    NA;

    public static Operation parse(String input) {
        Operation operation = EnumUtils.getEnum(Operation.class, input);
        if (operation == null) {
            return NA;
        }
        return operation;
    }

    public boolean isCount() {
        return this == COUNTA;
    }

    public boolean isSum() {
        return this == SUM;
    }

    public boolean isCountOrSum() {
        return this == COUNTA || this == SUM;
    }

}

Git move files - stop applying CRLF against my SQL file!

by GarciaPL on Friday 6 April 2018

Recently, I was trying to move some files, mostly .java's and.sql's, from one maven module into another one. We were just trying to merge two modules into one module, because of we thought that keeping two modules with pretty the same functionality is odd.

The main point around this movement was to preserve the history of changes made to those files in the past. Everything was fine until we tried to deploy the application on the server. Of course, I forgot to mention that we were using Flyway as a database migration tool. Unexpectedly, one of the file's checksum was not the same as the checksum saved in the database for that SQL file (flyway_schema_history table). We were astonished because of the content of the file did not change at all... but Pull Request on BitBucket was saying that there is a difference. We checked the MD5 for that file before and after the move, it was the same, but for some reason the checksum detected by Flyway was different! To be honest, we spent a lot of time trying to understand why it's happening, and then I found this post made by Richard Tuin [1].

The solution was just to revert moving of those SQL files up to the previous location and try to create a file called .gitattributes. We defined over there just a single line which was disabling CRLF for that single file for which checksum was not the same as this one stored in flyway schema history table. After moving SQL files once again, using git mv [2] command and uploading results on BitBucket, everything was fine!

The content of .gitattributes for that single file should look as below :

fileName.sql -crlf


References :
[1] Richard Tuin - How to make git ignore different line endings
[2] Git mv
[3] Git attributes












Non-blocking IO / Reactive programming - explanation

by GarciaPL on Monday 2 April 2018

Last time I was looking for an explanation what this "Non-Blocking IO" means. It was hard to understand what it's not blocking and what exactly it does or does not. Moreover, I was trying to find information how this correlates with reactive programming in overall... and I found it! Please check article listed in References. Thanks Adam!

In an old approach called threaded blocking IO, we bound every new connection to a new socket and create a new thread to process the data. This means that there is a single open connection which is managed by the single thread. When a client requests a connection from the server socket it sends back a new socket to communicate with. Now multiple connections can be handled until the limit of the maximum number of threads is reached. Each thread requires memory allocation, so while the concurrent connection goes up, the performance of the server goes down.

Instead of binding the thread to a connection, a notification is sent when the data is ready to read from a buffer. NIO uses buffers instead of streams to read/write data because data is processed when it's already there, not when it's actually being received. With this mechanism, multiple connections can be handled by one thread. That's how finally no threads are blocked while waiting on the IO.
The thread is only responsible for reading the buffers when it's notified about the arrival of any new data. This mechanism is called the 'event loop'. Following that logic, lots of concurrent connections can be handled with just a couple of threads. That's why NIO-based servers are so awesome and serve as our first building blocks.

Reactive programming is about using asynchronous, non-blocking building blocks with a functional style of coding.


References :
[1] Kotlindevelopment.com - Developers guide to Webflux

Compare two beans with DiffBuilder

by GarciaPL on Thursday 15 March 2018

Would you like to compare properties of two, not related beans? Are you tired of using Comparable interface from Java ? You might use a class called DiffBuilder which is a part of Apache Commons !

DiffResult diffResult = new DiffBuilder(firstBean, secondBean, ToStringStyle.SHORT_PREFIX_STYLE)
                        .append("id", firstBean.getId(), secondBean.getId())
                        .append("type", firstBean.getType(), secondBean.getType())
                        .append("conditionName", firstBean.getOther(), secondBean.getOther())

boolean hasDifference = diffResult.getNumberOfDiffs() != 0


Reference : [1] DiffBuilder - Apache Commons

Remove password from your pdf payslips

by GarciaPL on Thursday 22 February 2018

Within my previous employers, I was getting those payslips protected with a password. One day I thought what is going to happen if I would forget or lose the password! That's why I decided to write a small script in Python which might automate removing password from your payslip (or any other file).


# Requirements:
# pip install PyPDF2

import os
from PyPDF2 import PdfFileReader, PdfFileWriter

password = 'password'
directory = '/path/where/pdfs/are/stored'

def decrypt_pdf(input_path, output_path, password):
  with open(input_path, 'rb') as input_file, \
    open(output_path, 'wb') as output_file:
    reader = PdfFileReader(input_file)
    reader.decrypt(password)

    writer = PdfFileWriter()

    for i in range(reader.getNumPages()):
      writer.addPage(reader.getPage(i))

    writer.write(output_file)

if __name__ == '__main__':
  newDirectory = directory + "/Decoded"
  if not os.path.exists(newDirectory):
    os.makedirs(newDirectory)
  for filename in os.listdir(directory):
    if filename.endswith(".pdf"): 
      fullFileName = os.path.join(directory, filename)
      decrypt_pdf(fullFileName, newDirectory + "/" + filename, password)

Reference :
[1] Pastebin

Excel Power Query - Load JSON as a table

by GarciaPL on Sunday 18 February 2018

If you would like to load JSON and present it as a table, it's quite easy if you have an Excel 2016 [1]. It's more complicated, once you have a lower version.

First of all, try to install an additional plugin called Power Query [2].

In the Power Query ribbon tab, click From Other Sources > Blank Query, then go to Advanced Editor and input below query string. Do not forget to change the path to your JSON.

Click -> Close & Load

let

Source = Json.Document(File.Contents("Z:\Directory\input.json")),
AsTable = Table.FromRecords(Source)

in

AsTable

Click on 'Close & Load'
Reference :
[1] Microsoft Support - Connect to a JSON file
[2] Power Query for Excel

Creating release notes based on git commit history

by GarciaPL

If your JIRA does not support generating release notes because of for instance you do not fulfil Version field like in my case, there is a way to generate it based on git commit history.

First of all, you need to install a package called git-release-notes [2] via npm. It will allow you to generate release note page from git commit history using the following command :

git-release-notes 2.2.2..HEAD markdown.ejs > changelog.md

Of course, 2.2.2 is a git tag.

You might also use mentioned above template called markdown.ejs which has been written in EJS [3]. In my opinion, this template gives more control in terms how release notes will look like at the end. Of course, you might also depend on built-in template into git-release-notes module.

<% commits.forEach(function (commit) { %>
    <% if(!commit.title.startsWith('[maven-release-plugin]')) { %>
        <%= 'http://jira.com/browse/' + commit.title -%>
    <% } %>
<% }) %>


References :
[1] Confluence.atlassian.com - Creating release notes
[2] NPM - git-release-notes
[3] Ejs.co

Removing duplicates by field/property in Java 8

by GarciaPL on Friday 9 February 2018

How to remove duplicates in Java 8 using field or property ? We might use reduce!

List<MyClass> distinctByField = myList.stream().reduce(new ArrayList<>(), (List<MyClass> accumulator, MyClass myClass) -> {
    if (accumulator.stream().noneMatch(item -> item.getField().equals(myClass.getField()))) {
        accumulator.add(MyClass);
    }
    return accumulator;
}, (acc1, acc2) -> {
    acc1.addAll(acc2);
    return acc1;
});