How to add <base> element to page header in ZK Framework

Sometimes it is useful to create <base> tag in a page header. This is easy when you have access to html files. It’s not so simple when you are on ZK Framework. This short snippet shows it should be done in a ZUL file:

<zk>
<zscript><![CDATA[ page.addBeforeHeadTags("<base href=\"http://localhost:8080/your-webapp/\" />"); ]]></zscript>
<!-- your zk elements -->
</zk>

[MongoDB] How to add a field to a subdocument of every document in a collection?

Let’s say that a collection named items:

{
    "_id" : "a",
    "authorization" : {
        "group1" : "lrw",
        "group2" : "lr-"
    }
},
{
    "_id" : "b",
    "authorization" : {
        "group1" : "lrw",
        "group2" : "lr-"
    }
},
{
    "_id" : "c",
    "authorization" : {
        "group1" : "lrw",
        "group2" : "lr-"
    }
}

Now I would like to add a field to every “authorization”. The field may look like this:

{ "group3" : "lrw" }

Here’s the query that does that:

db.items.find({}).forEach(item => {
    db.items.update(
        { _id: item._id },
        { $set: { "authorization.group3": "lrw" } }
    )    
});

git status shows that files are modified but.. they are not!

This can be a real pain. You are working on git repo to which many developers with different OS (and with different line endings) contribute.
So, you have such a repo and at some time you may notice that some files which are marked as if they had been modified. You try to git checkout, reset, clean, but nothing helps…
It happens because of the wrong interpretation of line ending characters. This case is described here and here.
But actually the command suggested there did not help in my last case (and I lost more than two hours). Eventually, the following command solved the issue:

git config core.filemode false

Web components & Polymer how-to

How to invoke method from outside of a Polymer component when you’re in in a *.zul file from ZK Framework?

Polymer Element:

<script src="https://www.polymer-project.org/components/webcomponentsjs/webcomponents.js"></script>
<link rel="import" href="https://www.polymer-project.org/components/polymer/polymer.html">
<dom-module id="my-component">
	<template></template>
	<script>
		Polymer({
			is: "my-component",
			alert: function() { alert("alert!"); }
		});
	</script>
</dom-module>

Sample usage:

<zk xmlns:n="native" xmlns:w="client">
	<n:my-component id="myComponent"></n:my-component>
	<button id="someButton" w:onClick="document.querySelector('#myComponent').alert()">Click Me</button>
</zk> 

How to attach event listener to custom Polymer component and propagate event to server side using zAu?

The event is fired inside of a Polymer element using fire() method:

     this.fire('close-finish', "more detailed data", { bubbles: false });		

Native JavaScript below adds a new event listener to the component. Event handler executes zAu engine command to forward the event to the server.

    <n:script xmlns:n="native">
        document.querySelector('my-component').addEventListener('close-finish',
        function() {
        zAu.send(new zk.Event(zk.Widget.$('$cancelButton'), 'onClick', 'finish', {toServer:true}));
        });
    </n:script>

Some handy code for JVM8

How to map with casting in Java8

Original code:

Stream.of(objects)
 .filter(c -> c instanceof Client)
 .map(c -> (Client) c)
 .map(Client::getID)
 .forEach(System.out::println);

Better one:

Stream.of(objects)
 .filter(Client.class::isInstance)
 .map(Client.class::cast)
 .map(Client::getID)
 .forEach(System.out::println);

How to convert an array to Stream?

Stream<String> str = Arrays.stream(array);
 str.forEach(x -> System.out.println(x));

How to find duplicates in a list?

The following snippet will filter out null values from the given list and then leave only those elements which are duplicated:

List<String> list = 
 Lists.newArrayList("aa", "bb", "cc", null, "aa", "bb", "aa", null, null);
 list.stream()
  .filter(Objects::nonNull)
  .filter(tag -> Collections.frequency(list, tag) > 1)
  .collect(Collectors.toSet())
  .forEach(System.out::println);

The results of the above code is aa, bb.

Do it online

Online programming editors/debuggers are getting popular. Here are the couple of them which I use from time to time:

  • IDEOne – a broad choice of programming languages (there is even BrainF**k, however, there is no XSLT)
  • jsFiddle – a nice IDE for JavaScript.
  • jsBin – another one for JavaScript
  • XSLTCake – useful IDE for XSLT. It is still ‘beta’, but it offers three types of XSLT processing (JavaScript, web service or .NET 4.0)
  • XML Playground – another cool IDE for XSL templates. Unfortunately it doesn’t support XSLT 2.0
  • Rubular – IDE for checking regular expression written in Ruby
  • XSLTTest – Small and neat application for XSLT. Supports XSLT 2.0.

Useful XSLT snippet with translate()

Let’s say there is a following function written in XSLT 2.0:

    <xsl:function name="str:convertBits">
        <xsl:param name="cpnNumber" />

        <xsl:choose>
            <xsl:when test="$cpnNumber = 1">
                <xsl:value-of>8</xsl:value-of>
            </xsl:when>
            <xsl:when test="$cpnNumber = 2">
                <xsl:value-of>4</xsl:value-of>
            </xsl:when>
            <xsl:when test="$cpnNumber = 3">
                <xsl:value-of>2</xsl:value-of>
            </xsl:when>
            <xsl:when test="$cpnNumber = 4">
               <xsl:value-of>1</xsl:value-of>
            </xsl:when>
            <xsl:otherwise>
               <xsl:value-of>0</xsl:value-of>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>

Quite long, isn’t it?

This is how it can be shortened:

number(translate(xs:string($cpnNumbers[1]), '1234567890', '8421000000'))

How to change XML to lower case using XSLT multi-pass?

Today I’ve resolved another issue using XSLT multi-pass technique presented in my previous post. I think this be might useful in future, so I post it here. The XSLT translates the input XML to lower case (it changes only node names, it doesn’t affect data inside elements or attributes). After that, it applies the actual logic.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="firstPassResult">
<xsl:apply-templates select="/" mode="firstPass"/>
</xsl:variable>
<xsl:template match="@*|node()" mode="firstPass">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" mode="firstPass">
<xsl:element name="{translate(name(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="$firstPassResult" mode="secondPass"/>
</xsl:template>
<xsl:template match="//boss" mode="secondPass">
<xsl:value-of select="text()"/>
</xsl:template>
</xsl:stylesheet>

The sample XML file (only to prove that this technique works):

<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Boss>John</Boss>
<BoSs>Henry</BoSs>
<BOSS>Nathan</BOSS>
<boss>igor</boss>
</Root>

It worked under Altova XMLSpy and produced the following output:

<?xml version="1.0" encoding="UTF-8"?>JohnHenryNathanigor

How to get rid of empty attributes in XSLT output?

Some time ago, I faced an issue related to XSLT stylesheets. It was while we were developing quite complex XSLT template whose purpose was to convert one  XML  into completely different another one. During the implementation, it turned out that the output XML contains a lot unnecessary empty attributes, e.g.:

<field attr="" />

It was actually possible to get rid of them with <xsl:if> or <xsl:choose> instructions. However, it would require one conditional instruction per one <xsl:attribute…/> instruction. This would make the XSLT file too complex. So I needed other approach, that would act after the basic transform. And this is achievable by usage of

multi-pass XSLT transforms.

Let’s say that we have the following input XML:

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<database>
<record firstName=\"john\" lastName=\"smith\">writer</record>
</database>

We would like to have the above XML converted by this XSLT transform:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output indent="yes" exclude-result-prefixes="xs xsl"/>

    <xsl:template match="/database/record">
        <output>
            <xsl:attribute name="firstName">
                <xsl:value-of select="@firstName"/>
            </xsl:attribute>
            <xsl:attribute name="lastName">
                <xsl:value-of select="@firstName"/>
            </xsl:attribute>
            <xsl:attribute name="middleName">
                <xsl:value-of select="@middleName"/>
            </xsl:attribute>
            <xsl:attribute name="dob">
                <xsl:value-of select="@dob"/>
            </xsl:attribute>
            <xsl:text>recordFound</xsl:text>
        </output>
    </xsl:template>
</xsl:stylesheet>

The output looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<output firstName="john" lastName="john" middleName="" dob="">recordFound</output>

As you can see there are two empty attributes: middlename and dob. And this is where we can think about multi-pass transforms. We would like to have another transform applied on the results of the this XSLT.

Now, let’s consider what should be done to remove empty attributes. This is very to accomplish using identity transforms. This is simple variant of identity transform that removes empty attributes:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:template match="node()|@*" >
        <xsl:copy>
             <xsl:apply-templates select="@*[.!='']" />
             <xsl:apply-templates select="node()" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

What is left is merging our both  XSLTs. The following code is the final XSLT transformation. We are using modes that are available XSLT 2.0. We store the result of our business operation in the variable $firstPassResult and we perform the removal of empty attributes on it.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">    
    <xsl:output indent="yes" exclude-result-prefixes="xs xsl"/>
    <xsl:variable name="firstPassResult">
        <xsl:apply-templates select="/" mode="firstPass" />
    </xsl:variable>

    <xsl:template match="/database/record" mode="firstPass">
        <output>
            <xsl:attribute name="firstName">
                <xsl:value-of select="@firstName"/>
            </xsl:attribute>
            <xsl:attribute name="lastName">
                <xsl:value-of select="@firstName"/>
            </xsl:attribute>
            <xsl:attribute name="middleName">
                <xsl:value-of select="@middleName"/>
            </xsl:attribute>
            <xsl:attribute name="dob">
                <xsl:value-of select="@dob"/>
            </xsl:attribute>
            <xsl:text>recordFound</xsl:text>
        </output>
    </xsl:template>

    <xsl:template match="/">
        <xsl:apply-templates select="$firstPassResult"
            mode="secondPass" />
    </xsl:template>

    <xsl:template match="node()|@*" mode="secondPass">
        <xsl:copy>
             <xsl:apply-templates select="@*[.!='']" mode="secondPass"/>
             <xsl:apply-templates select="node()" mode="secondPass"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>