Encoding from UTF-8 to ISO: The *ever* ending story

For certain reasons the problem of encoding failures seems to be a never ending story – in some programming languages more (Perl :-D, PHP,…), in some less (Java!).
It’s not a secret that Microsoft Excel has a hard time opening non-native files, such as CSV, in the right encoding. At least on Excel 2013 for Mac, the probem persists as long as the user double clicks a document instead of using the “import wizard”, which allows to specify the encoding.

So in this case I had written a Groovy script that exports a CSV file – logically UTF-8 encoded. Then the customer complained about crippled characters – yes, the never ending story.
Nevermind, I thought, I’ll convert the document to the German ISO-8859-15, an easy task done in one line:

String isoCsv = new String(originalCsv.getBytes('UTF-8'), Charset.forName("ISO-8859-15"))

The string produced this way turned out to be UTF-8 again, not ISO.
Many attempts later, my dear colleague and Señor Developer “Simon the Sourcerer” drew my attention to this thread on stackoverflow.com proposing to use Buffers.

And yes, apparently this approach works very well.
So, the end(!) of the story looks like this method:

public byte[] convertToISO8859(byte[] stringBytes) {
        ByteBuffer inputBuffer = ByteBuffer.wrap(stringBytes);
        CharBuffer charBuffer = Charset.forName("UTF-8").decode(inputBuffer) // decode UTF-8
        ByteBuffer outputBuffer = Charset.forName("ISO-8859-15").encode(charBuffer) // encode ISO-8559-15
        return outputBuffer.array()
    }

Executing Bash scripts with Groovy

Groovy is an ideal language if you want to quickly execute scripts – but you’re of course not limited to Groovy Scripts, though. Sometimes it’s the quickest way to write Bash scripts, especially for simple file operations.

Jenkins for example offers a neat console to execute Groovy code.
But what if you’d like to use Bash scripts? Nothing easier than that! Groovy offers the execute() method on GStrings.

So all you want to write is

println “ls -lR ~/.m2”.execute().text

if you want to find out what directories have been created by maven2 in your local repository.

Have fun!


Serving a blind GIF from a String in Grails

If you have a requirement that needs to be implemented, the first thing to do is probably using Google to avoid re-inventing the wheel. Today I wanted to include a “tracking pixel”, usually a blind GIF, in a Grails controller. But instead of reading out the GIF with each request, I asked myself if it wouldn’t be much wiser to store the GIF (with its 45Bytes) as final static String.

I googled Matthew’s blog post, where it’s exactly described. In Grails it’s even a bit nicer :-). Anyway, it’s so easy. See:

import org.springframework.security.core.codec.Base64

class TrackingController {

  // see http://is.gd/GCuJX3
  private static final String PIXEL_B64 = "R0lGODlhAQABAPAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
  private static final byte[] PIXEL_BYTES = Base64.decode(PIXEL_B64.getBytes())

  // send the tracking pixel and write statistics
  def track() {

   // track the request here...
   // send the GIF image
   response.setContentType("image/gif")
   response.outputStream << PIXEL_BYTES
   return // this statement is required.
 }
}

As opposed to Matthew’s blog post, I’m using Springs Base64 decoder because we have the dependency to Spring in Grails anyway.
Use the import org.springframework.security.core.codec.Base64.
And that’s it!


Putting Java, Groovy and Maven together using GMaven

I’ve recently been working on a “pure” Java project that was built with Maven only. We started to begin working on a new Java/Maven module that is intended to read certain database tables’ columns with certain rules (e.g. plaintext, XML, and others). It’s pretty obvious that it’s smarter to use “speaking” methods like

getHeadlineAsPlaintext()

than

getDbColumn(“headline”, PlainTextEditor.class);

So I introduced Groovy. Everything worked fine – until I realized that the integration tests involving these dynamic method calls also required to be Groovy classes. Working with IntelliJ that wasn’t really a big deal – just adapt the class path accordingly. You can even place your groovy sources files within src/main/java.

However, Maven was pretty stubborn with that. First, you need to know that you must include the GMaven plugin in order to compile your Groovy classes to Java Bytecode in the necessary lifecycles. Secondly, if you follow the conventions of this plugin, you must place your Groovy files in src/main/groovy and src/test/groovy. Simple as in Grails, but not if IntelliJ can run everything and you wonder why Maven complains (well, actually Maven complains every time about details but that’s another topic…).

So with Gmaven, we’ve got the missing piece. Now you need to make sure that you include the correct dependencies. You must know that GMaven normally itself has a dependency to groovy-all. It’s best to exclude this dependency, otherwise you’ll obviously run into runtime problems with missing methods and that stuff.

Also note that there are different versions of the GMaven plugin which are bound to distinct Groovy versions.

For our project, we are glad to use Groovy 2.0. Luckily, Guillaume Laforge has published a brilliant article on how to include GMaven with the latest Groovy dependency:

http://glaforge.appspot.com/article/building-your-groovy-2-0-projects-with-maven

Now:

mvn clean compile test 🙂


How to stream to multiple AirPlay(tm) devices without iTunes(tm) and without Airport Express(tm)

In my previous posts I wrote about the Zeppelin Air, and in fact, I’m using it as on of my several music speakers to fill my rooms with fine music :-). I’ve always dreamed of a “music” house. AirPlay seems to be the right solution at this time, because Sonos and Logitech (Squeezebox) are strictly restricted to the hardware produced by themselves (i.e. you must buy a Sonos speaker when you’ve got a Sonos system), whereas Apple is licensing its AirPlay technology to other “premium producers” such as Bower&Wilkins. Recently some amplifiers with AirPlay support have been presented.

Unfortunately, Apple tries to enforce us to stream our music only from within iTunes. But what if you’d like to stream your favorite music that is playing in a web browser, because you’re using spotify, simfy, Napster, just to name a few? No way.

What if you like to receive AirPlay streams on other devices? Apple would now answer “Well, for this purpose you can by the AirPort Express(tm)” which acts as AirPlay receiver and offers both analog and digital stereo output. Actually, you’d be better off buying AppleTV3 with even more features for just 20€ more, but that’s not necessary if you only intend to stream music (for video streaming it can be a smart solution, though).

But we can do better and save 80€ :). Airfoil (available for both Mac and Windows) allows you to select an arbitrary input source and serves it as AirPlay audio stream.

Airfoil for Macintosh screenshot Believe me, this little software is worth every cent, though it’s not for free – check the website.

The screenshot shows Airfoil on my Mac. I’m currently listening to music being played in the Chrome browser. The different receivers can be selected just by clicking on them, you can also see the Zeppelin. All other AirPlay would be mentioned here, too.

The “Computer”  is the Mac running Airfoil. “SilverApple” is my old white MacBook running the free AirSpeakers software, allowing to act as receiver for Airfoil. This Mac is connected to my hi-fi system with 4 speakers, treating the living room with sound :-).

But this is just the beginning:

If you have a device running iOS such as an iPhone or iPod, you can use “Airfoil Speakers Touch”. Welcome to the future! Now you can even attach your iPhone/iPod/… to the hi-fi system without Airport Express or other hardware. Now – that’s cool, isn’t it?

By the way, I’m now using Airfoil for over 1 year and so I can say it’s really reliable. No interruptions, no crashes, as I’ve already said: Just worth every Cent 🙂

 

Feel free to leave a comment if you like this post or if you have any questions.

More on this topic:
Read Peter Ledbrook’s very interesting article about his experience on switching WiFi channels when he had trouble with AirPlay


Getting the most of your B&W Zeppelin Air(tm) and how to prevent interruptions while streaming

How to prevent interruptions

While the B&W Zeppelin Air is popular for its excellent sound, it’s also popular for connection problems when playing music over WiFi using AirPlay. Sadly enough to say that this feature is so common that everybody complians about it when using the Zeppelin for the first time – including myself…

I’m now using the Zeppelin Air for nearly one year and got some experience in how to prevent interruptions. I’m using a MacBook with OS X 10.6 and 10.7 and a standard router by TP (model TL-WR941N). It seems that the problems are related to the AirPlay protocol but not OS X or Windows, but that’s just an assumption.

At this point of time, I haven’t fully figured all the factors that lead to interruptions.

I finally found a setup allowing me to listen to AirPlay streams without any breaks – I hope the following points help you to achieve the same :-).

In order to avoid streaming problems, consider the following points – importance in this order:

  1. First and foremost, connect your streaming source (i.e. the Mac or PC) to a cable network. DO NOT CONNECT IT BY WiFi to the network! I found out that not the Zeppelin as receiver is the real problem but the sender device.
  2. If you don’t have an ethernet connection at hand, consider buying a “ethernet over powerline” solution. If myself use the TP-Link 200 MBPs and it’s working perfectly. It’s not expensive (about 30€).
  3. Use DHCP in the Zeppelin’s menu, but do not give any other information. The configuration should look like the following screenshot:
  4. In your network router’s configuration, assign a fixed IP address based on the MAC address to the Zeppelin Air. That way you can always access the Zeppelin’s configuration over the same IP address in your browser.
  5. On the device streaming your music, try to avoid using the network bandwith by downloading/uploading other data because there are no mechanism on your router giving the “AirPlay stream’s packets” priority over other data
  6. Try to avoid interferences with other Wireless Networks by choosing a channel that is not used by other WiFi networks in your neighbourhood. On the Mac, KisMac is one of the best tools to find out other networks and their channels / frequences.
  7. Keep in mind that the Zeppelin is not able to use Wireless 11but only 11b and 11g. Consequently I’m using the 11bgn mixed mode, so other devices (such as the Mac) can take advantage of higher bandwiths.
  8. Apply the latest firmware (at this point of time version 1.03.01)
  9. If the network settings do not work, consider resetting the Zeppelin’s settings (see the manual and several Youtube videos for explanations on how to do this).
  10. In order to enforce the Zeppelin to connect again to the network, always fully disconnect the Zeppelin from the power source and make sure the red LED has switched off.
  11. Because I was tired to re-enter my WiFi’s password each time, I’m now using an unsecured WiFi with hidden SSID. I strongly discourage this if you’re not in an area where other persons have physical access to your WiFi!!! I do not know if the connection interruptions are related to encryption issues. I’ve also used the Zeppelin with WPA2 without any problems.

 

Please leave your comment if this article helped to solve the Zeppelin’s connection problems :-).


Why I decided for B&W’s Zeppelin Air(tm) music system

I love music. More than 15 years ago, I bought a Denon(tm) 2.1 system consting of high quality speakers and an amplifier, and I’m still happy with it. I paid 800 DM – which was quite a bunch of money at this point of time! I rather pay a bit more in order to get a ‘mature’ system in order to be happy for the next 5-10 years.

As you might know I’m also loving Apple products as they incorporate quality (high prices, haha), elegant design and smart solutions. The same applies to Bower&Wilkins’ Zeppelin speaker. While the first generation of the Zeppelin already was very successful, its successor, presented in 2011, additionally comes up with Apple’s AirPlay technology, which means you can stream music over iTunes WiFi WLAN to up to 10 devices with AirPlay support and being in the same WiFi.

Before I bought the B&W Zeppelin, I evaluated other music systems. You know, I want to be happy with it for the next 10 years, so this was obligatory :-).

  1. I tried out a system by Philips (price: 300€) with CD player and Bluetooth streaming support. The design was quite good, but the sound was so poor that I questioned Philips’ competence in music. I sent back the device the next day. Thanks Amazon…
  2. Then I went to a BOSE(tm) store located in one of Hamburg’s most famous malls. The BOSE SoundDock 10, about 500€, was recommended to me. The sound quality was very good, but I disliked the optical appereance (grey in grey, a bit frumpy). More important, this product did not support AirPlay but only Bluetooth stream (and: the Bluetooth adapter should cost 100€ plus!), so I would not be able to stream my music to any other devices at the same time.
  3. I went to Wiesenhavern, one of Hamburg’s oldest stores for HiFi. The only system that could ever compete with B&W’s Zeppelin in sound quality and design was the Geneva-M (and Geneva-L) speaker – stylish and excellent sound. Price: 500€ and more.

All in all, these reasons made me buy the B&W Zeppelin Air:

  • excellent sound – very balanced, present but not too strong subs, fine tweeter.  The balanced sound scales very well, no matter if playing loud or quiet music
  • excellent design. I like it a lot and fell in love at once
  • AirPlay support allowing me to stream to more devices connected to the WiFi
  • Although the price of 600€ is quite high, it’s fair with regard to the superior performance. Plus, other products with less features were in the same range of 500-600€.

The next article will describe how to stream to more than one device using AirPlay and how to prevent interruptions.


Converting Java Properties bundle files into ‘readable’ UTF-8

The property files found in Java message bundles are somewhat a ‘historical relic’ of former times, when Java was not quite UTF’ed as it is nowadays. Actually, I’ve never understood why the guys did not decide to give up the ISO-8859-1 encoding, e.g. by providing a Properties constructor allowing to pass in ‘boolean UTF-8 = true’.
Frankly spoken, using IntelliJ with its fantastic feature of converting all characters of the UTF-8 universe transparently, I myself as developer don’t have any problems with encoding or encrypted characters at all. But what will the customer say, seeing these ugly sequences of escaped \u0015 characters? …

Well, for this you’re probably lucky to find the following Groovy script which allows for reading in a properties file and printing out its expected representation on standard.out.
Here we go – have fun!

#!/usr/bin/env groovy
import static groovy.io.FileType.*
import java.io.*;
import java.util.Properties;

if (args.size() != 1) {
System.err.println("Usage: ${this.class.name} [ your-file.properties")
  System.exit(1)
}

File propFile = new File(args[0])
if (!propFile.exists()) {
System.err.println("Error: unable to open file " + propFile.name)
  System.exit(1)
}

PrintStream out = new PrintStream(System.out, true, "UTF-8");

Properties properties = new Properties();
properties.load(new FileInputStream(propFile))
def keys = properties.keySet().sort() as List
for (String key : keys) {
  out.println(key + '=' + properties.get(key))
}


Groovy: No need to use substring()

Groovy’s range operators are just great.

If you’ve came across the problem to cut a string’s last 2 characters, in Java, you’d probably write something like this:

int s = theString.length()
String cutChars = theString.substring(0, s)

In Groovy you don’t need that stuff.
Just use

String cutChars = theString[0..-3]
and you’re done :-).

By the way, how would you write this in Java in one line:

String s = “CU soon!”
assert s[-1..0] == “!noos UC”

Have fun!


why SimpleDateFormatter isn’t really simple with Locales

In a recent project several languages such as Finnish, Italian, Greek, Chinese and others are used.

As the project deals with assessing survey data and dates, it’s self-evident to have date pickers that show the months names in the respective country representation. It was reported that errors occur when trying to save  a form, however, only when Greek, Finnish or Italian were chosen. Then I came across the part in the code where the actual dates are parsed. E.g. for Greek, it looks like…

String dateStr = “01 Μάρτιος 2012”;
String format = “dd MMM yyyy”;
Locale locale = new Locale(“el”, “GR”);
SimpleDateFormat sdf = new SimpleDateFormat(format, locale);

The date format uses “MMM” to indicate the the full month name is expected. Note that the SimpleDateFormat needs the Greek locale in order to be able to parse Μάρτιος (i.e. ‘March’).
Month names are often shown in a short form. For example, in Germany dates can be represented like 29. Feb. 2012 – which is 29th of Feburary in 2012. These kind of representations can be parsed using the format “dd. MM. yyyy”, indicating that the month’s short name is expected.

Escecially for Greek, which makes use of UTF8 characters, this however didn’t work (or I’ve overseen some detail?). Instead, only full month names were accepted by the SimpleDateFormatter.
Use this list for representing January…December:

‘Ιανουάριος’, ‘Φεβρουάριος’, ‘Μάρτιος’, ‘Απρίλιος’, ‘Μάιος’, ‘Ιούνιος’, ‘Ιούλιος’, ‘Αύγουστος’, ‘Σεπτέμβριος’, ‘Οκτώβριος’, ‘Νοέμβριος’, ‘Δεκέμβριος’

Furthermore, I stumbled upon the Finnish month names. Using Google translator, I was surprised to find that there are obviously non-unique month names in the Finnish language, and for some month names, the translator even didn’t find any matches . For March, there is the word ‘Maalis’ and ‘Marssia’. The DateFormatter only accepts the first one.
Here is the full list of ‘parseable’ Finnish months names:

‘Tammikuu’, ‘Helmikuu’, ‘Maalis’, ‘Huhtikuu’, ‘Toukokuu’, ‘Kesäkuu’, ‘Heinäkuu’, ‘Elokuu’, ‘Syyskuu’, ‘Lokakuu’, ‘Marraskuu’, ‘Joulukuu’

If you’ve similar experiences, please leave a comment.