Assign <#nested> to variable in FreeMarker

FreeMarker is awesome template engine. I'm still wonder how much powerful it is and how flexible it can be when you need. Last week, when I was writing a simple macro to render tweets using user defined template, my though was that it may be good to define this template as macro nested content. For instance:

<@tweets 'rkhmelyuk', 10>
[picture] [username]: <br/>
[message]<br/>
<a href="[url]">[date]</a>
</@tweets>

Pretty simple, but the only way for me was to load tweets using Twitter API through JSONP protocol. So my macro was need to generate a javascript code, that should correctly define callback and fetch tweets. Callback function simply applies received JSON data to the user defined template.

And here is the problem. How to get macro's nested content into javascript variable? Well, who ever used FreeMarker knows that nested content can be rendered with command <#nested/>. This could be a solution, but isn't. Why? Because I need to do extra preparing of template to put it as a javascript string. I need to remove newlines and replace quotes. So the best decision is to put nested content as Freemarker variable and do preparation over it first and than insert into javascript. And here is the power of Freemarker. This was possible and easy to do with <#assign/> or <#local/> command:

<#local layout><#nested/></#local>
<#-- Now layout variable contains a template defined as nested -->
<script type="text/javascript">
function callback_${id}(data) {
var layout = "${layout?SomePreparationsGoHere}";
renderTweets(layout, data);
}
</script>

In this code, the nested content is assigned to variable layout. Then we generates a javascript code and insert layout variable as string, but first do some preparations.

I also like flexibility of Freemarker. I hope that could find a time and describe some other tips about it soon.

Facebook was failing to parse OG meta tags

Last week was having awful time fighting with strange work of Facebook. We had a page with OG meta tags and a Facebook Like button on the page. And Facebook was discarding to parse the page and extract data from OG meta tags. Using URL linter didn't help to find the problem but show the same information - page isn't parsed, OG meta tags are not used.

So I tried to check next things to find the issue:

  • whether property attribute in used <meta/> tags

  • whether correct fb:app_id meta tag value is set

  • whether nginx returns correct page when facebook requests the page

  • whether correct namespaces added to the <html/> tag

  • whether we are using UTF-8 encoding

  • and something other, don't remember all my tests

And was checking web page through URL Linter each time. With no success. Facebook discarded parsing the page and fetching page title with other data from meta tags.

So I reviewed response/request data through firebug to find suspicious things. I found one scanty detail: Content-Type header had value "text/html;charset=utf-8;charset=UTF-8".
I must say, this one web page is generated by application using user-defined template. Grails controller is responsible for handling request and renders output like:

render text: context.out, contentType: "text/html;charset=$AppConstant.RENDER_CHARSET"

where AppConstant.RENDER_CHARSET equals to "UTF-8". But the rendered page had Content-Type equal to "text/html;charset=utf-8;charset=UTF-8". And my thought was to fix header value to have something like "text/thml;charset=UTF-8" and hoped this may help. So I changed code to be like:

render text: context.out, contentType: "text/html"

Content-Type header value now is "text/html;charset=utf-8". So I tried URL Lint again. I wasn't expecting much from Facebook this time either, but miracle happened! Everything works fine now. I know, that is my fault, but, nevertheless, thank you Facebook for "nice" time spending :).

Linux tools to generate password

Few days ago was looking for simple tool to generate passwords in linux console.
As result of my searching are 3 useful tools. They are:

  • apg

  • makepasswd

  • pwgen


apg


Install: sudo apt-get install apg

Asks to enter random data, that should be used to generate new password.
Example:

Please enter some random data (only first 16 are significant)
(eg. your old password):>
Opt8Ovuf (Opt-EIGHT-Ov-uf)
Uc1Gryec (Uc-ONE-Gryec)
jadJoav5 (jad-Joav-FIVE)
IshtIvawam3 (Isht-Iv-aw-am-THREE)
lakVosAfUrg7 (lak-Vos-Af-Urg-SEVEN)
dyijDus8 (dyij-Dus-EIGHT)

You can pass random string as parameter and use many different options:

$ apg -n 10 -m 8 -x 12 somerandomdata

Will generate 10 passwords with min length 8 and max length 12.

makepasswd


Install: sudo apt-get install makepasswd

Generates password, by default one. User may need to use options to set length of password and count of passwords. For example:

$ makepasswd --count=10 --minchars=5 --maxchars=10

Results:

mzd4f9q
gUWamL
NYiUXrYvq3
6hWDXKA
gQpu20IJGD
BSAT5ASFX
37FcKyLPb
ma7pC66A
cFpWPBy
0oTNhT7


pwgen


Install: sudo apt-get install pwgen

My favorite tool to generate password. By default generates 160 different passwords each with length 8 symbol. Programs takes 2 parameters:
- 1st is the length of the password and
- 2nd is the count of passwords to generates. For example:

$ pwgen 12 24

Results:

oHo2iethieze cheiS6ohPeed Oozufiorohv9 eic3aethei4L hiRohYie6Ue4 aephoiDieb0y
hieTh8eizaeK aid1EeNgaiSe yoh6chohX9ha aiPhae7dieMe wedooD8nai7y aic7deeB9eS8
ohFor3Achied Thaequu4aiph zaeghiem7keT Shee5ooxaex0 wePh2eiNgien aicohroo2Go3
Aagh0gahcah0 Zie8eazaitah aoha9AeXi7Bo Oojoob0oosh6 Olahgh4aeji6 oobae9UZ2phi

Open Source: core library

Few months ago, after I moved to GitHub, one of my util projects was open sourced. It was, simply called, core: https://github.com/rkhmelyuk/core. I have written this library few years ago and was actively using on Java projects. In some places it crosses with Apache Commons Lang library, but I, actually, like my child more :)

I'd like to describe some key classes and show samples of use. Some of them are enumerated below.

StringUtils contains few oftenly used methods, like:

  • isEmpty(), isBlank(), isNotEmpty(), isNotBlank(), isBlankTrimmed(), isNotBlankTrimmed() - used to check whether string is empty or not. The difference between empty and blank, is that empty is either null or empty string, while blank is always blank string and can't be null.

  • cut() - used to cut string if length is more than specified and appends with specified suffix. The only difference is that this method tries to split by space, so don't cut the word. Sample:

    String string = "some string goes here";
    assertEquals "some string...", StringUtils.cut(string, 15, "...");

  • trimIfNotNull() - if input string is not null, then trim it and return result:

    String string = " Hello ";
    assertEqual "Hello", StringUtils.trimIfNotNull(string);
    assertNull StringUtils.trimIfNotNull(null);

  • replaceNotAlphaNumeric() - replace all characters that are not letter or digit with specified one or "_" by default.


ConversionUtils contains some simple but useful methods to convert string value to numeric and boolean types. Contains methods getInteger(), getLong(), getBoolean(), getDouble(), getDate(), getFloat():

assertEquals 1, ConversionUtils.getInteger("1");
assertNull ConversionUtils.getInteger("hello");
assertEquals 5, ConversionUtils.getInteger("hello", 5);

KeyGenerator was created to generate API keys, passwords and other random stuff. It has one highly configurable method and few helpful methods that uses it. There is a way to generate keys with alpha and/or numeric and/or special symbols.

That would be hard to write assertions for samples, but here are simple use cases:

KeyGenerator.generateKey(10, KeyGenerator.WITH_ALPHA_LOW | KeyGenerator.WITH_ALPHA_UP);
KeyGenerator.generateStrongKey(100);
KeyGenerator.generateSimpleKey(20);
KeyGenerator.generateAlphaKey(20);

After I found some issues with Apache Commons-Lang ToStringBuilder, I wrote my own replacement, and called it... ToStringBuilder :) It is very simple in use:

class Blog {
private String name;
private String author;
private int year;

public String toString() {
new ToStringBuilder(Blog.class)
.field("name", name)
.field("author", author)
.field("year", year)
.toString();
}
}

Blog blog = new Blog();
blog.setName("Java UA");
blog.setAuthor("Ruslan Khmelyuk");
blog.setYear(2010);

assertEquals "Blog[name=Java UA, author=Ruslan Khmelyuk, year=2010]", blog.toString();

There are much more interesting tools, like ArgumentAssert and StateAssert used to assert arguments and program state respectively.

CollectionUtils also contains few useful methods, and I'm not going to describe them here.

Library is open to review and use. Still it's definitely not the best one and, I think, has value only for me.

Neverending Groovy: map with default values

More and more Groovy openings for me every day!

Just today, I found that there is a way to setup default value for map entry, if absent. In some cases it may be very handy.

For example, I need to prepare a map with words counts. This simple task should be coded simple too, like:

def map = [:]
words.each { word -> map[word]++ }

But it's not working and fails with NPE exception. Why? Because it's hard to increment null.

Although, there is simple way to avoid this problem even using Groovy API:

def map = [:]
words.each { word -> map[word] = map.get('word', 0) + 1

Here 2nd parameter of map.get() method is the default value, returned if there is no value for key 'word'. And now it's working fine!
Still there is another way, and, as for me, it helps to make code clean and safe. Safe because default logic can be used elsewhere we want to use our map object.

def map = [:].withDefault { 0 }
words.each { word -> map[word]++ }


I bet there is a better way and I'm going to find it...