Swift’s Nil Coalescing Operator AKA the “?? Operator” or “Double Question Mark Operator”

This last week I was introduced to quite a funky little operator in Swift called the Nil Coalescing operator. It is basically a shorthand for the ternary conditional operator when used to test for nil.

For example traditionally in many programming languages you could do something like this to check for nil/null…

stringVar != nil ? stringVar! : "a default string"

Here if the condition is not nil the value of stringVar will be returned otherwise the value “a default string” is returned.

This can be shortened in Swift by using the Nil Coalescing operator.

stringVar ?? "a default string"

This does exactly the same thing, if stringVar is not nil then it is returned, however if it is nil the value “a default string” is returned.

Love it.

Technorati Tags: , , , , , , , , ,

Long time no posts.

Woah just realised it’s been 4 years since I last did a techie post, and 2 since the last non-techie one.  I hope to start writing more regular posts again.

Well since 2010 I’ve been learning iOS development and so the blog will probably focus a bit more on that from now on.

How To Pass A Null Value To A Custom Tag Library

Today I found something very interesting.  I wanted to pass a java.math.BigDecimal to a custom JSP Tag Library and format it as a percentage, however if the BigDecimal was null I didn’t want to show it.

Easy, I thought. So I created a class similar to the following…

package name.kayley.blog.taglib;

import java.io.IOException;
import java.math.BigDecimal;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

public class BigDecimalTagSupport extends TagSupport {
    
    private BigDecimal value;
    
    public void setValue(BigDecimal value) {
        this.value = value;
    }
	
    public int doEndTag() throws JspException {
        try {
            if (value != null) {
                pageContext.getOut().print(formatAsPercentage(value));
            }
        } catch (IOException e) {
            throw new JspException(e);
        }
        return EVAL_PAGE;
    }
...
}

However, when I called this taglib with a null value I still got a value of 0.

    <mytag:bigDecimal value="${aBigDecimal}" />

The output:
0

After a bit of trial and error I discovered that the JSP tab library framework does a little bit of magic on known classes, such as Strings and Numeric objects. Classes of Numeric types that are null get converted to 0 and Strings get converted into the empty string ""

I discovered that if you change your internal value to an java.lang.Object instead of a java.math.BigDecimal the magic doesn’t know what to do and just passes null to your class.

So the new class looks like the following…


package name.kayley.blog.taglib;

import java.io.IOException;
import java.math.BigDecimal;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

public class BigDecimalTagSupport extends TagSupport {

	private Object value;
	
	public void setValue(Object value) {
		this.value = value;
	}
	
	public int doEndTag() throws JspException {
	    try {
	    	if (value != null) {
	    		// Cast value to a BigDecimal if you need to.
			    pageContext.getOut().print(formatAsPercentage(value));
	    	}
		} catch (IOException e) {
			throw new JspException(e);
		}
		return EVAL_PAGE;
	}
...
}

So now when I use the tag and pass a null BigDecimal to it I get the required result of no output.

WIN

I have an example web app demonstrating this, if anyone wants a copy just let me know.

Technorati Tags: , , , , ,

 

Pay At The Pump and LPG Finder for BlackBerry(R)

For the past few months on and off I’ve been working on a project for my friend and former colleague John Haselden of Abstractec. He has made a website and an iPhone phone application which utilises web services of the website. The project is called Fuelista, and the applications are Pay at the Pump and iPayAtThePump for iPhone, (with variants for LPG etc).

The idea of the Pay at the Pump and LPG Finder applications is to provide a location based service to allow you to find petrol stations that provide a “pay at the pump” or “LPG” service. The application does a GPS lookup on your location, and returns a list of garages that provide that service. You can then navigate through and get more details of the garage, and if you require you can a route from your current location to the garage.

Abstractec are trying out more platforms than just the iPhone. They are investigating Android, BlackBerry and PalmPre. I was asked if I would like a go at the BlackBerry port, so I thought “why not?”

I wanted to get into writing iPhone applications for fun and maybe a bit of extra cash, I bought myself a Macbook Pro and an iPhone in mid 2009, but there is a lot to learn to get up and running with iPhone development, the applications are written in Objective-C and the development environment is quite difficult to get your head around when you’re starting off, especially coming from a Java background.
BlackBerry applications however are written using Java.

Research In Motion (RIM) provide a layer on top of J2ME providing their own classes and UI components specifically for the BlackBerry handsets.

The application is complete and also I have created the LPG equivalent. Check out the video below for a demo of the application. The GPS lookup on the handset that I have to test with is quite poor…Hence the timeout when the first lookup occurs.

Enjoy…



Technorati Tags: , , , , , ,

How to Avoid ClassCastExceptions when using Hibernate Proxied Objects

Recently at work I was faced with an issue on the live system. A certain page within the application would only show the system’s standard error message. After looking in the logs I discovered there was a ClassCastException being thrown, this was due to the fact that a lazily loaded List of objects retrieved by hibernate contained proxied objects. The entities that were proxied were using a single table inheritance strategy, so there is a base class that is subclassed several times. The entities once loaded were being sorted into separate lists that are typed according to the subclasses, they were being cast into the appropriate subclass but this cast was failing because instead of being an instance of say Animal it was an instance of Animal$$EnhancerByCGLIB$$10db1483 i.e. A Hibernate Proxy. Let me show you an example.

So lets say we have a base class that has an inheritance strategy set…

package name.kayley.cglibexample;

import javax.persistence.*;

@Entity
@Table(name="animals")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name="animal_type_id",
    discriminatorType=DiscriminatorType.INTEGER
)
public class Animal {

    @Id
    @GeneratedValue
    private Long id;
    
    @Column
    private String name;
    
    @Column
    private Integer age;
    
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

And then we had 2 subclasses of this Animal class, lets say, Cat and Dog


package name.kayley.cglibexample;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue("1")
public class Cat extends Animal {
   // some cat specific attributes
}


package name.kayley.cglibexample;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue("2")
public class Dog extends Animal {
   // some dog specific attributes
}

As you can see the discriminator column is animal_type_id, which I have defined 2 to be Dog and 1 to be Cat. So now we should make sure we have some data in a database table called animals…

SELECT id,animal_type_id,name,age FROM animals a LIMIT 0,1000

'id', 'animal_type_id', 'name', 'age'
1, 2, 'Scooby', 3
2, 1, 'Felix', 4
3, 1, 'Garfield', 4

Right so to recreate a similar situation I will show you a unit test that will pass! What I am trying to do is to retrieve the list of animals and sort them in the java into separate lists, a list of dogs and a list of cats..

public void testCGLibInstanceOfError() throws Exception {

    List dogs = new ArrayList();
    List cats = new ArrayList();

    Iterator it = hibernateDao.createQuery("from Animal").iterate();

    while (it.hasNext()) {

        Animal animal = it.next();
        assertTrue(animal.getClass().getName().contains("Animal$$EnhancerByCGLIB$$"));
                    
        if (animal instanceof Cat) {
            cats.add((Cat) animal);
        } 
        else if (animal instanceof Dog) {
            dogs.add((Dog) animal);
        }
    }
    assertEquals(0, dogs.size());
    assertEquals(0, cats.size());
}

Now using the data in the database we want a list of 1 dog and a list of 2 cats. Here I’m being particularly evil and using instanceof to differentiate these. The assertEquals at the end of the test pass, even though the code looks like it should be adding items to these lists based on what is in the database. This is because animal is not an instanceof Cat or Dog but an instanceof Animal$$EnhancerByCGLIB$$10db1483.

So how do we solve this issue?

I first thought about using Hibernate.initialize(animal); which will force the animal class to become the actual object, not the proxy. I felt this approach to be dirty and it is really polluting code that shouldn’t really know anything about hibernate.

So I did some googling and after reading the hibernate documentation and then this I set about using the Gang Of Four Visitor Pattern.

First we need a visitor interface that we can implement in your test…

package name.kayley.cglibexample;

public interface AnimalEntityVisitor {
    void visit(Dog dog);
    void visit(Cat cat);
}

Next we need is an interface for our Animal class to implement…

package name.kayley.cglibexample;

public interface AnimalEntity {
    void accept(AnimalEntityVisitor visitor);
}

Now we make our Animal class I showed earlier implement the AnimalEntity


package name.kayley.cglibexample;

import javax.persistence.*;

@Entity
@Table(name="animals")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name="animal_type_id",
    discriminatorType=DiscriminatorType.INTEGER
)
public abstract class Animal implements AnimalEntity {
   ...
   // see top of post
   ...
}

And next implement the method in the subclasses..


package name.kayley.cglibexample;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue("1")
public class Cat extends Animal {
   // some cat specific attributes

   public void accept(AnimalEntityVisitor visitor) {
      visitor.visit(this);
   }
}


package name.kayley.cglibexample;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue("2")
public class Dog extends Animal {
   // some dog specific attributes

   public void accept(AnimalEntityVisitor visitor) {
      visitor.visit(this);
   }
}

All we need to do is implement the visitor in our test…


public class MyTest 
    extends AbstractTransactionalDataSourceSpringContextTests 
    implements AnimalEntityVisitor {

        ...
    // some spring setup     
        ...

    private List dogs = new ArrayList();
    private List cats = new ArrayList();
    
    public void testCGLibUsingVisitor() throws Exception {

        Iterator it = hibernateDao.createQuery("from Animal").iterate();

        while (it.hasNext()) {

            Animal animal = it.next();

            assertTrue(animal.getClass().getName().contains("Animal$$EnhancerByCGLIB$$"));

            animal.accept(this);
            
        }
        assertEquals(1, dogs.size());
        assertEquals(2, cats.size());
    }

    public void visit(Dog dog) {
        dogs.add(dog);
    }

    public void visit(Cat cat) {
        cats.add(cat);
    }
}

So instead of using instanceof or having to cast anything (which is what was happening in the live code I talked about) which can cause weird side effects and ClassCastExceptions, you can just use this visitor pattern. What happens is the test is implementing the AnimalEntityVisitor, so when animal.accept(this); is called, it calls the appropriate visit method on “this”. In our case the visit method is just adding the object to a list. So I’ve updated the assertEquals calls to be what I now expect and the test passes.
Happy days, enjoy!
Technorati Tags: , , , , , ,

How to Undelete files removed with “rm” in Ubuntu

Recently I found myself in a situation where I needed to recover some files I accidentally deleted. I had written a program in Java to read off a JBoss Messaging Dead Letter Queue, and save them in a format that could be re-inputted back into the system.

So my program was writing files into a directory within my home directory, and while I was testing the program I was not committing back to JMS so ensure the messages stayed there. When I was confident that the program was correct, I added the commit, I then removed the files that my tests had produce by using “rm *”.

I then ran my program for real. In the directory I was expecting files to appear I typed the usual “ls -ltr” to see a list of files. I pressed the up key to run the last command i.e. “ls -ltr” to see some more files created. I repeated this a few times, until I accidentally pressed the up key twice…..yep you guessed it….”rm *”, the files were deleted and the commit to JMS means they were no longer on the queue. My heart sank.

Now I rememebered on the old days of DOS there was an UNDELETE command, so I was looking around the web to see if there was something similar for Linux. I was in luck, especially as my program was still running.

Basically thanks to this information, I recovered my deleted files with relative ease. 🙂

Ok so to do this, I believe you need to be as fortunate as I was and still have the program that created the deleted files still running, so let’s create a Java program that will write to a file and then keep running…


package name.kayley.undeletefiletest;

import java.io.FileWriter;
import java.io.PrintWriter;

public class UndeleteFileTest {
 public static void main(String[] args) throws Exception {  
  FileWriter writer = new FileWriter("/tmp/testFile.txt");
  
  PrintWriter printer = new PrintWriter(writer);
  
  printer.append("hello this file is going to be deleted.");
  printer.flush();
  Object lock = new Object();
  
  synchronized(lock) {
   lock.wait();
  }
 }
}

Ok, now run that program and it will create a file in /tmp called testFile.txt, so lets see it..


andy@andy-laptop:/tmp$ ls -ltr *.txt
-rw-r--r-- 1 andy andy 39 2009-02-13 18:54 testFile.txt

So we can see the file is there, lets delete it to see if we can recover it…

andy@andy-laptop:/tmp$ rm testFile.txt

Now the file is gone. So how do we get it back? Well first we need to find the PID of the process that created the file that was deleted. We know that it was a java program that created it so we’ll use the lsof and search for java..

andy@andy-laptop:/tmp$ lsof | grep java
.....[lots of things listed]
java      9048       andy    4r      REG        8,1       39 1622029 /tmp/testFile.txt (deleted)

No now we know the PID is 9048 lets find the file… so there should be a directory /proc/[PID]/fd…


andy@andy-laptop:/tmp$ cd /proc/9048/fd
andy@andy-laptop:/proc/9048/fd$ ls -ltr
total 0
lr-x------ 1 andy andy 64 2009-02-13 18:54 4 -> /tmp/testFile.txt (deleted)
l-wx------ 1 andy andy 64 2009-02-13 18:54 3 -> /usr/local/jdk1.6.0_07/jre/lib/rt.jar
l-wx------ 1 andy andy 64 2009-02-13 18:54 2 -> pipe:[43665]
l-wx------ 1 andy andy 64 2009-02-13 18:54 1 -> pipe:[43664]
lr-x------ 1 andy andy 64 2009-02-13 18:54 0 -> pipe:[43663]

Bingo! We have found the deleted file, so now all we need to do is cat the link to a new file, so here I put it into my home directory…


andy@andy-laptop:/proc/9048/fd$ cat 4 > ~/testFile.txt

Next, I go to my home folder and have a look at the file, and hey presto…its restored…


andy@andy-laptop:/proc/9048/fd$ cd
andy@andy-laptop:~$ less testFile.txt 
hello this file is going to be deleted.
testFile.txt (END) 

Technorati Tags: , , , , ,