New Safe Methods Added to kSOAP2

Lately I have been using the kSOAP2 library for SOAP communications on Android. The library is not particularly elegant, but it gets the job done. It also appears to no longer be maintained and a nasty bug with SoapObject#getAttribute was getting in my way. Thankfully, Manfred Moser’s fork fixed the bug and saved my butt.

An example of the library’s inelegance is in the way SoapObject’s getAttribute and getProperty work when the item doesn’t exist. Instead of returning null, it throws a RuntimeException. This might be acceptable if there were methods for asking whether a property or attribute exist on the SoapObject, but there aren’t. Thus, you’re forced into using exceptions for control purposes, which we all know is poor and highly annoying to work with.

After some discussion with Manfred about it, I went ahead and added several methods to SoapObject:

  1. public boolean hasAttribute(String name) will return true if the attribute exists and false if not.
  2. public Object safeGetAttribute(String name) will return the attribute if it exists and null if not.
  3. public boolean hasProperty(String name) will return true if the property exists and false if not.
  4. public Object safeGetProperty(String name) will return the property if it exists and NullSoapObject if not.
  5. public Object safeGetProperty(String name, Object defaultThing) will return the property if it exists and defaultThing if not.

The last two items bear some explanation. I found myself writing some code against a SOAP structure that looked something like this:



  1999
  Hudsonville High School


The problem I had is that sometimes subelements of education would be completely missing. This made the following code break:


public void extractEducationDetails(SoapObject education, IEducationDetails details) {
  details.setYear(education.getProperty("year").toString());
  details.setSchool(education.getProperty("school").toString());
}


SoapObject#safeGetProperty improves the situation by returning a NullSoapObject, which simply returns null from toString(). Now my code looks like this:


public void extractEducationDetails(SoapObject education, IEducationDetails details) {
  details.setYear(education.safeGetProperty("year").toString());
  details.setSchool(education.safeGetProperty("school").toString());
}


and I get neither RuntimeException@s or @NullPointerException@s flying out of this method when @year or school are missing.

Though my downstream code handles it fine, I thought it was a little weird for toString() to return null all the time. That’s what public Object safeGetProperty(String name, Object defaultThing) is for—you can return whatever you want when the property doesn’t exist. So, if my downstream code prefers blank strings over null, then I can do this:



public void extractEducationDetails(SoapObject education, IEducationDetails details) {
  details.setYear(education.safeGetProperty("year", "").toString());
  details.setSchool(education.safeGetProperty("school", "").toString());
}

These changes are available from my fork of kSOAP2 on GitHub. Manfred plans on pulling in the changes once he’s available later in the month.

Edit October 12, 2010: Manfred has now taken ownership of the kSOAP2-android project and brought these changes into the mainline. Thanks to Manfred for doing this – maintaining a long-living open source library is not easy!