Scala: Calling higher-order functions on Maps


As I’m learning Scala, I played with Maps. The subtlety of Maps has to do with the fact that they are tuples of (key,value) pairs. Let’s look at the various ways of calling higher-order functions on them.

Let’s consider a map of bears and they weights created as follows.

scala> val myMap = Map("Brown Bear" -> 635, "Grizzly Bear" -> 360, "American Black Bear" -> 270, "Polar Bear" -> 680)
myMap: scala.collection.immutable.Map[String,Int] = Map(Brown Bear -> 635, Grizzly Bear -> 360, American Black Bear -> 270, Polar Bear -> 680)

Filtering bears that weigh more than 300kg

If I want to filter bears that weigh more than 300kg, I’ll use the filter function. I can do it by passing in a function (x) => x._2 > 300.

scala> myMap.filter((x) => x._2 > 300)
res0: scala.collection.immutable.Map[String,Int] = Map(Brown Bear -> 635, Grizzly Bear -> 360, Polar Bear -> 680)

I can also use a wildcard instead of defining defining the parameter x.

scala> myMap.filter(_._2 > 300)
res0: scala.collection.immutable.Map[String,Int] = Map(Brown Bear -> 635, Grizzly Bear -> 360, Polar Bear -> 680)

A third way would be to use a case in order have the tuple split for us into its two parts as input to the function.

scala> myMap.filter {case (x,y) => y>300}
res2: scala.collection.immutable.Map[String,Int] = Map(Brown Bear -> 635, Grizzly Bear -> 360, Polar Bear -> 680)

As I don’t car about the first part of the tuple, I can just use a wildcard instead of (x,y).

scala> myMap.filter {case (_,y) => y>300}
res12: scala.collection.immutable.Map[String,Int] = Map(Brown Bear -> 635, Grizzly Bear -> 360, Polar Bear -> 680)

Averaging the weights of the bears

Let’s say that I want to average the weight of the various bears. To do so, I have to use foldLeft on the map and then divide the outcome by the size of the map.

scala> myMap.foldLeft (0) ((sum,v) => sum+v._2) / myMap.size
res5: Int = 486

Instead of using defining the signature of the anonymous function, I can also use wildcards.

scala> myMap.foldLeft (0) (_+_._2) / myMap.size
res7: Int = 486

Now I can even use the scala shorthand for foldLeft even though I’m no real fan of it.

scala> (0/:myMap) (_+_._2) / myMap.size
res9: Int = 486

The shorthand is equivalent to the following as methods that end with a colon associate to the right.

scala> (myMap./:(0)) (_+_._2) / myMap.size
res10: Int = 486

Actually, the easiest way can also be to directly work on the values and call the sum function on those values.

scala> myMap.values.sum / myMap.size
res6: Int = 486

Averaging the weights of the bears that weigh more than 300kg

If I now want to average the weights of the bears that weight more than 300kg, I can first filter the weights that are greater than 300kg. I can  do that by filtering a Map and returning a Map using filter. I can also filter the values by first calling values

Let’s first calculate the average on the filtered list of values.

scala> myMap.values.filter(_>300).sum / myMap.size
res18: Int = 418

Let’s now do it by always working on a Map and using FoldLeft.

scala> myMap.filter(_._2>300).foldLeft(0)(_+_._2) / myMap.size
res0: Int = 418

Final thoughts

With Scala, there are so many ways to do the same thing that in the end, it’s just a matter or taste. Nevertheless, when working in a team, it’s good practice to try to keep the style uniform throughout the code base.

This post did not aim at listing all the possible ways to implement the examples. Given the nature of Scala, I even imagine that there are more clever ways to do it.

A last consideration has to do with performance. Given the size of my example, all solutions run pretty fast. This shall no doubt be different with larger collections.

Calculating a value whether one column of several is not null in PL/SQL


I wanted to calculate in a SQL query whether one of three columns in a table was not null. I did not want to do it in the Java code to keep code clean.

First, I started to used DECODE and NVL2 to reproduce a kind of IF-THEN-ELSE to lazily compare my values:

IF <field one> IS NOT NULL THEN true ELSE IF <field two> IS NOT NULL THEN true ELSE IF <field three> IS NOT NULL THEN true ELSE FALSE

This was a bit convoluted and resulted in the following code:

SELECT DECODE(NVL2(remarks_f, 'true','false'), 'true', 'true','false',DECODE(NVL2(remarks_n, 'true','false'), 'true', 'true','false',DECODE(NVL2(remarks_d, 'true','false'), 'true', 'true','false','false'))) AS hasRemarks
FROM bulletin;

After discussion with a colleague of mine, he suggested that I concatenated the values of the three fields and check whether the outcome was null or not like:

IF <field one> + <field two> + <field three> IS NOT NULL THEN true ELSE FALSE

This resulted in the following code:

SELECT DECODE(NVL2(remarks_f || remarks_n || remarks_d, 'true','false'), 'true', 'true','false','false') AS hasRemarks
FROM bulletin;

Then, I realised that NVL2 was more than enough to achieve what I wanted and I ended up with the following code:

SELECT NVL2(remarks_f || remarks_n || remarks_d, 'true','false') AS hasRemarks
FROM bulletin;

Highlighting input fields with CSS and JQuery


The interface of our current Web Application is rather complex and contains loads of fields. The end users wanted us to make the active field or element more visible. The only hitch is that the supported browsers are IE7, IE8 and Firefox 3.6+.

The CSS dynamic pseudo-class :focus should have done the trick. The :focus selector is supported as such by Firefox, Chrome and IE9.

Here is an example of how to use it. Don’t pay attention to the ugliness of the outcome :-). In the case of the check box and radion I could only manage to change the border style and width and not the colour.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<style type="text/css">
input:focus, textarea:focus, select:focus {
        background: #FFFFCC;
        border: 2px solid red
}
</style>
</head>

<body>
            Text Field: <input type="text" /><br />
            Password Field: <input type="password" /><br />
            Text Area: <textarea></textarea><br />
            Radio Button: <input type="radio" /><br />
            Check box: <input type="checkbox" /><br />
            Button: <input type="submit" value="Submit" /><br />
            Select box:<select>
                                  <option>One</option>
                                  <option>Two</option>
                                  <option>Three</option>
                                  </select> <br />
</body>
</html>

To make it work in IE8, the page must declare a <!DOCTYPE>, as illustrated below. Furthermore, one must disable the compatibility view settings for the Web site in order to have the CSS working. Go to Tools->Compatibility View Settings and uncheck the adequate check boxes.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Unfortunately, that does not work in IE7. However, I found a JQuery plugin that makes it work with IE7 at http://james.padolsey.com/javascript/fixing-focus-in-internet-explorer/. The only problem that I found was with select, that does not work.

Here is an example of how to use it:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<style type="text/css">
input:focus, textarea:focus, select:focus {
        background: #FFFFCC;
        border: 2px solid red
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>
<script type="text/javascript" src="pseudofocus.js"></script>

</head>

<body>
            Text Field: <input type="text" /><br />
            Password Field: <input type="password" /><br />
            Text Area: <textarea></textarea><br />
            Radio Button: <input type="radio" /><br />
            Check box: <input type="checkbox" /><br />
            Button: <input type="submit" value="Submit" /><br />
            Select box:<select>
                                  <option>One</option>
                                  <option>Two</option>
                                  <option>Three</option>
                                  </select> <br />
        <script type="text/javascript">
            $.pseudoFocus();
        </script>
</body>
</html>

Links

Fixing MW_HOME problem with the Domain Wizard in WebLogic 11g


After having installed a WebLogic server on my Ubuntu machine, I wanted to use the wizard to create a domain. I then ran into the following problem when I ran the configure.sh script

$ ./configure.sh

./configure.sh: 19: [[: not found ./configure.sh: 19: -d: not found ERROR: You must set MW_HOME and it must point to a directory. where an installation of WebLogic exists. Ensure you point this variable to the extract location of the zip distribution. config.sh

The problem is simple. The first line of the script as it comes out of the box is

#!/bin/sh

In order to run it properly, I changed that first line to refer to bash as follows

#!/bin/bash

That did the trick

Installing Oracle SQL Developer on Ubuntu


Update: As I switched to Linux Mint, I ran into an permission problem. To have it working, follow the procedure available at http://community.linuxmint.com/tutorial/view/938, which provides additional steps.


On my current project, we use Oracle database. The best free tool I have found so far to work with the database as a Java developer is Oracle SQL Developer.

Oracle does not provide a package for Debian based distros. I tried to run the tool from the generic archive but it failed to run because it seems to be aiming at another environment with respect to the Swing look and feel that it failed to load.  After some googling, I found that there is a package to make a package (sqldeveloper-package)out of the archive to make it installable as such.

Here is how to use it.

Download Oracle SQL Developer

As the download requires that one have an Oracle account, I download it from the browser at the following address: http://www.oracle.com/technetwork/developer-tools/sql-developer/sqldev-ea-download-486950.html

Install Java

See my post Install Sun JDK 6 on Ubuntu 11.10

Install the sqldeveloper-package and its dependencies

$ sudo apt-get install sqldeveloper-package debhelper

 Install dos2unix

$ sudo apt-get install tofrodos

It is necessary to create the following symlinks for the tool to work:

$ sudo ln -s fromdos dos2unix
$ sudo ln -s todos unix2dos

Make the deb package

It seems that the -b switch can be used to indicate where to generate the .deb but it does not seem to work (Or I did not spend enough time trying to get it to work). The tool will generate the .deb in the working directory.

$ cd ~/Downloads
$ make-sqldeveloper-package ~/Downloads/sqldeveloper-3.1.06.44-no-jre.zip

Install the package

$ sudo dpkg -i sqldeveloper_3.1.06.44+0.2.3-1_all.deb

The tool is now available in Applications->Programming->Sql Developer

Install Sun JDK 6 on Ubuntu 11.10


Update 2011-12-20: Following up on comments on the post, I added a section on how to  configure the Java Browser Plugin in manual installation

Update 2011-11-25: I added the information regarding the configuration of the JDK as in my previous post  Configuring Java on Kubuntu 10.10


Since Ubuntu 11.10, there is no longer an official package for the Sun/Oracle JDK. The package sun-java6-jdk is no longer officially available.

Method 1: Install a package provided by a PPA

There is a PPA (Personal Package Archives) made available by Roberto Ferramosca. To add this PPA, run the following command from the command line:

    $ sudo add-apt-repository ppa:ferramroberto/java
    $ sudo apt-get update

You can now install the JDK with the following command:

    $ sudo apt-get install sun-java6-jdk

I you’d like to install the JRE or the Java Plugin along with the JDK, use the following:

sudo apt-get install sun-java6-jdk sun-java6-jre sun-java6-plugin sun-java6-fonts

You must now set the Sun JDK as the default. You can see how to achieve this in a previous post Configuring Java on Kubuntu 10.10.

The benefit of this method is that the JDK will be updated when a newer version of the package is made available.

Method 2: Installing the JDK manually

This method consists of downloading the adequate JDK from the Oracle Web site. The file is a bin file, e.g. jdk-6u29-linux-x64.bin

The first step is to create a temporary folder where we’ll download the file.

    $ mkdir -p ~/tmp/jdk-6u29
    $ cd ~/tmp/jdk-6u29

Once downloaded, make the file executable and run it.

    $ chmod +x jdk-6u29-linux-x64.bin
    $ ./jdk-6u29-linux-x64.bin

Now copy the file to the preferred target location, e.g. ~/dev/jdk

    $ mkdir -p ~/dev/jdk
    $ cd ..
    $ mv jdk-6u29 ~/dev/jdk/

Let’s now create a symbolic link so that we can easily update with newer versions in the future.

    $ cd ~/dev/jdk
    $ ln -s jdk-6u29 jdk-6

The next step is to add to the ~/.bashrc the path to our JDK binary files.

    #Use the symbolic link
    export JAVA_HOME="~/dev/jdk/jdk-6"
    export PATH=$PATH:$JAVA_HOME/bin

That’s it.

The benefit of this method is that one can install any version of the JDK (6 or 7). The downside is that one must manually upgrade the JDK.

Manually configuring the browser plugin

To configure the plugin, you need the JRE that comes with the JDK. If you installed the JDK in $JAVA_HOME, the JRE is located in $JAVA_HOME/jre.

Based on some documentation that I found on Oracle Web Site, the solution is simply to create symlinks to the plugin. The plugin can be found in

  • $JAVA_HOME/jre/lib/amd64/libnpjp2.so for 64bit machines
  • $JAVA_HOME/jre/lib/i386/libnpjp2.so for 32bit machines

You can go to http://javatester.org/version.html to check that the plugin works fine.

Configuring the plugin for Firefox

Create a symlink to the plugin

$ sudo ln -s $JAVA_HOME/jre/lib/amd64/libnpjp2.so /usr/lib/firefox-addons/plugins/libnpjp2.so

This shall do the trick.

Configuring the plugin for Chromium

Create a symlink to the plugin

$ sudo ln -s $JAVA_HOME/jre/lib/amd64/libnpjp2.so /usr/lib/chromium-browser/plugins/libnpjp2.so

With Chromium, it is necessary to enable plugins. You can just launch it from the command line once to enable the plugins with the following command

$ chromium-browser --enable-plugins %U

If you now naviate to chrome://plugins/, you shall see something like:

Java – Version: 1.6.0.30
The next generation Java plug-in for Mozilla browsers.
Disable

Activating a default Maven profile defined in settings.xml with other profiles in the pom.xml


In Apache Maven, there are different places to configure profiles:

  • The project pom.xml
  • The user’s settings.xml
  • The installations settings.xml

I wanted every developer to be able to customise the build properties independently of the pom.xml. It is a very bad practice to have everyone modifying the pom.xml locally. One would also argue that it is a very bad practice to have developers customise build properties. That’s a debate for another time 🙂

The profiles that we have are:

  • Development (default)
  • Jenkins (continuous integration)
  • Test
  • Acceptance
  • Production

The profiles define the target environment for the build.

At first, I tried to define a profile as activeByDefault in the settings.xml file while setting the other profiles in the pom.xml not active by default. That did not work at all because in this case the profile defined in the settings.xml is active at any time and overrides other profiles.

The solution that I found was to use a property to activate a profile. The profile defined in the settings.xml is the Development profile. It would be activated by the absence of such a property. Indeed, it would be boring to have to specify a property for most of the builds.

The settings.xml looks like this:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
	  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
			      http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <profiles>
    <profile>
      <id>Development</id>
      <activation>
	<property>
	  <name>!env</name><!-- The exclamation mark indicates that the property shall be absent -->
	</property>
      </activation>
      <properties>
	<target.environment>Development</target.environment>
	...
      </properties>
    </profile>
  </profiles>
</settings>

When using the Maven command mvn help:active-profiles, it yields:

The following profiles are active:

 - Development (source: settings.xml)

The development profile is active if the property env is not set using the Maven command line parameter -Denv=xxx.

All the other profiles are defined in the pom.xml:

...
  <profiles>
    <profile>
      <id>Jenkins</id>
      <activation>
	<property>
	  <name>env</name>
	  <value>Jenkins</value> <!-- This is the value for that property that will activate the profile -->
	</property>
      </activation>
      <properties>
	<target.environment>ContinuousIntegration</target.environment>
	...
      </properties>
    </profile>
    <profile>
      <id>Test</id>
      <activation>
	<property>
	  <name>env</name>
	  <value>Test</value>
	</property>
      </activation>
      <properties>
	<target.environment>Test</target.environment>
	...
      </properties>
    </profile>
    <profile>
      <id>Acceptance</id>
      <activation>
	<property>
	  <name>env</name>
	  <value>Acceptance</value>
	</property>
      </activation>
      <properties>
	<target.environment>Acceptance</target.environment>
	...
      </properties>
    </profile>
    <profile>
      <id>Production</id>
      <activation>
	<property>
	  <name>env</name>
	  <value>Jenkins</value>
	</property>
      </activation>
      <properties>
	<target.environment>Production</target.environment>
	...
      </properties>
    </profile>
...

To activate any profile from the pom.xml instead of the Development profile, we just have to pass the env property to the command line. For example:

$ mvn -Denv=Test help:active-profiles

The command above yields the following result:

The following profiles are active:

 - Test (source: pom)

Considerations on configuring my GitHub account on a new Ubuntu install


I changed laptops and I needed to reconfigure my GitHub account.

At first, I wanted to reuse the SSH key that I used on my other computer, which works fine. Afterwards, I changed my mind as it is actually less hassle to generate a new key and to add it to my GitHub account. Once the new laptop was configured, I could remove the former key.

In any case, I first needed to install an SSH client in order to follow the setup guide from GitHub. I installed OpenSSH with the following command:

$ sudo apt-get install openssh-client

Then I could follow the procedure to generate a new key pair and configure my account.

If I had wanted to reuse my existing key and passphrase, I could have copied the following two files from my current computer to the ~/.ssh folder of the target computer.

  • ~/.ssh/id_rsa
  • ~/.ssh/id_rsa_pub

Using resource bundle keys containing dots in a facelet


In order to put some order into our resource bundle with JSF, I wanted to use dots to structure the keys to make them more meaningful. I wanted to use a structure like ScreenName.title=value

We used to use the keys this way

<h:outputText value="#{bundle.title}" />

When I tried to use

<h:outputText value="#{bundle.screen.title}" />

I got an error because JSF interpreted bundle.screen.title as an expression and title was not a method of the String class. To be able to use the dots, I had to change the way to get values from the bundle as follows:

<h:outputText value="#{bundle['screen.title']}" />

Ignoring Eclipse and Maven files and Folders with Git


The file .gitignore tells Git which files to ignore at commit time. The ignore file itself shall be added and committed to the repository.

Add the following lines to in order to ignore Eclipse project files and folders

.classpath
.project
.settings/

Add the following line to ignore Maven target folder:

target
%d bloggers like this: