Wednesday, December 29, 2010

Timezones, timezones and a new time zone library

I've had a bit of a thing about time zones and daylights savings rules for quite some time i.e. they interest me. This was first apparent in an application I wrote for the Palm OS originally named Time Traveler (which became Titan Class). Its time zone database was inspired by zoneinfo, but was no where near as sophisticated. The Palm OS was without time zone support in its first few incarnations. Eventually time zone support was incorporated but IMHO it was weak. I digress a little... the point is I've really liked the zoneinfo database that underpins most Unix based platforms for quite some time.

Java supports zoneinfo in its implementation by use of the ICU library. There is also a JSR that's about 3 years old which aims to provide greater support for zoneinfo.

I recently had a need to ensure that my application had the latest time zone rules available. From a Java perspective, Sun or Apple (or whoever) provide a patch when time zone rules change. You then typically restart your application. I didn't want that. My goals were:

  • to have the latest rules on a monthly basis; and
  • to be able to dynamically update the time zones without having to restart my application.

JSR-310 could probably help me out here but I had another nagging concern; in fact a couple:

  • the JSR is 3 years old and doesn't appear to have progressed; and
  • I like the zoneinfo structure and wanted to use something that honoured its structure closely.

I might be a little unfair toward JSR-310 and if it becomes approved then it'll be difficult to avoid. I'm also strongly aware of the "Not Invented Here" syndrome... not my style though. Then, there's the JCP-is-dead thingy...

So, what I've done is created a new Java time zone library that takes zoneinfo files and produces a JDK compatible facade. The library uses ANTLR to parse the zoneinfo files thus actually providing a parser that can be used for many languages. I'll shortly be open-sourcing this library and probably at The Codehaus depending on how well it is received there. Meanwhile here is an overview of its structure:

Zoneinfo TZ.png

The library is effectively done and has reasonable test coverage. I hope that you'll join me and help improve it. Meanwhile any thoughts and ideas are most welcome.

Tuesday, December 7, 2010

Memory grids

There's a great podcast on Software Engineering Radio with Nati Shalom. The podcast discusses memory grids and I certainly found it insightful. In essence memory grids are being looked upon as the next disk.

The clincher for me was the revelation that the durability of data is not related to it being persisted to disk; it is related to the number of geographically disbursed copies of that data at any one time. Taken to the extreme this could mean that you don't need disk at all, but practically the data gets persisted to disk in an asynchronous manner. This is called "write behind" and can be performed at n nodes, if not all of them.

I think memory grids are very interesting. My prediction is that memcached, a popular open source memory cache that can be distributed over many nodes, will become a memory grid offering write-behind persistence. Same goes for Ehcache/Terracotta i.e. these memory caches will evolve beyond being just that. There are of course commercial memory caches out there including vmware's Gemfire and Oracle's Coherence.

One reason in my mind as to why memory grids are topical is commodity hardware being able to address one heck of a lot of memory resident data. Since the introduction of 64 bit computing for the masses, we now have a situation where a cheap processor can generally access about 256TB data - more than enough for most databases! Of course, with 32 bit processors about 4GB could be addressed which is less than many databases.

I think something that can be overlooked with memory grids is persistence. As mentioned, write-behind appears typical, but what isn't focused on is what performs the write-behind. There's no reason why that write-behind can't be done with a conventional RDBMS and I understand that many memory grids support such a thing. Thus with memory grids, it appears that you can have the best of both worlds.

Bring on the memory grid (preferably open sourced!).

Saturday, November 6, 2010

Mac OS X Virtualisation

This evening I read that Apple are retiring the Xserve. I guess that's a shame as I always wanted to see more of OS X in the server space. I think that this will relegate OS X to the SOHO market; unless... Apple permit virtualised instances of OS X.

Permitting virtualisation would be a very smart move by Apple. Let's face it, unless you can run on OS as a virtualised instance then you're never going to be a player in the enterprise and in the elastic cloud.

Time will tell if Apple see the merits of virtualisation.

Thursday, November 4, 2010

JavaScript Dependency Management and JSLint Tools

I've been focusing on JavaScript Rich Internet Application development for some time now and have felt that while JavaScript is a capable language, it has sorely lacked tooling. This situation is changing of course and we're seeing more JavaScript tools come from the likes of Mozilla, Apple and Google quite frequently.

I feel that the lack of dependency management with good version control in any language is painful and JavaScript was no exception. I recently spent a good part of my day sorting out dependencies in a .NET environment; I sorely missed Apache Maven there. Given my JavaScript development activities I decided to provide the dependency management functionality of Maven to JavaScript via a Maven Plugin.

Imagine writing just the following in your JavaScript code when you want to ensure that jQuery or Prototype.js is present at runtime:

var $;

Alternatively when there are no global variables declared by a JavaScript dependency you can import it without being concerned about its file location and version:

/**
 * @import com.jqueryui:jquery-ui
 */

The com.jqueryui:jquery-ui artifact along with its version is declared in Maven's POM file.

This frictionless approach to declaring JavaScript dependency requirements is the motivation for the Maven JavaScript Import Plugin.

I'm pleased to announce the availability of my JavaScript Import Plugin at Codehaus where I have now also become a committer (a great honour!).

Along the way  I decided to create a plugin that provided efficient JSLint invocation during JavaScript development. This plug is also released at the Codehaus and is named the JSLint Plugin.

Please help the professional JavaScript developer community by downloading and building the projects from source and try out some development using the plugins.

Maven crashing with a bus error/invalid memory access given Java 10.6 update 3

I had this very annoying scenario where all of a sudden the following happened:

mvn
Invalid memory access of location 0x133cd800a rip=0x100504444
Bus error

This seemed to happen as a result of updating to Java 10.6 update 3 on Mac OS X Snow Leopard; but not straight away!

After a while I started to wonder if the update was installed correctly. So, I manually downloaded the update from here:

http://support.apple.com/kb/dl972

...and presto, things appear to be ok again... let's see how long that lasts!

I understand that as of this update, Apple are handing over control to Oracle in terms of managing the distribution of Java on Mac OS X. I think that this is generally good given that Apple has always been a little behind in terms of the latest Java release. Let's hope that the quality of the distro on Mac OS X does not go south though!


Wednesday, October 6, 2010

When is a unit test not a unit test?

There's a great deal written on this topic already, but obviously not enough. I had a very interesting chat with a colleague the other day about what constitutes a unit test vs integration, system etc.

I think the boundaries are mirky, but for me at least, a unit test is something that can be constructed with little friction and it can execute fast. I don't really care much about whether I'm testing things that are technically outside of the "unit" I'm working on e.g. if there's an in-memory database available and I can easily construct a test of my code, I don't think I'm crossing the boundary into integration testing. In fact what I've found is that it is sometimes easier to set up an  in memory database for the purposes of testing rather than mocking it.

Now of course when you start crossing process boundaries you are moving into the world of integration tests. This falls into the category of "being slow to run" though.

At the end of the day I'm not too worried about whether my test is a unit test so long as its easy to write and quick to execute. If it isn't then I'm happy to have it fall into another category of testing.

Saturday, August 7, 2010

A MessageBodyWriter isWriteable method for a collection example

I can’t believe how much time I’ve spent today on providing an isWritable method for my JAX-RS MessageBodyWriter class. I just couldn't find a good example out there that did what I wanted to do. Maybe Google search wasn't behaving today!

My goal was to have a provider that translates a List<GPSTrackerCollection> object into an application/xml output stream. GPSTrackerCollection is my own class.

The tricky thing was learning how to test for the presence of a List of GPSTrackerCollection objects within my provider.

First things first, I needed to wrap my collection in a GenericEntity object in order to preserve information on the parameterised type; the runtime strips this information of course (this is known as erasure). Here's an example service implementation from my code base:

@GET
@Path("/history")
public Response getHistory() {
List<GPSTrackerCollection> list = new ArrayList<GPSTrackerCollection>();
GenericEntity<List<GPSTrackerCollection>> entity =
new GenericEntity<List<GPSTrackerCollection>>(list) {};
return Response.ok(entity).build();
}

My MessageBodyWriter ends up looking something like the following:

@Produces("application/xml")
@Provider
public class GPSTrackerCollectionProvider implements
MessageBodyWriter<List<GPSTrackerCollection>> {

@Override
public long getSize(List<GPSTrackerCollection> arg0, Class<?> arg1,
Type arg2, Annotation[] arg3, MediaType arg4) {
return -1;
}

@Override
public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] arg2, MediaType arg3) {

// Ensure that we're handling only List<GPSTrackerCollection> objects.
boolean isWritable;
if (List.class.isAssignableFrom(type)
&& genericType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericType;
Type[] actualTypeArgs = (parameterizedType.getActualTypeArguments());
isWritable = (actualTypeArgs.length == 1 && actualTypeArgs[0]
.equals(GPSTrackerCollection.class));
} else {
isWritable = false;
}

return isWritable;
}

@Override
public void writeTo(List<GPSTrackerCollection> gpsTrackerCollections,
Class<?> arg1, Type arg2, Annotation[] arg3, MediaType arg4,
MultivaluedMap<String, Object> arg5, OutputStream os)
throws IOException {

...
}
}

The key thing here is that we check the parameterised type argument for equality against the class of GPSTrackerCollection. My intuition was that I could do an instanceof operation here, but this is not permitted. Check out this FAQ as to why.

Enjoy.

Saturday, July 31, 2010

Application development feelings 2010

Every now and again I review my practice of developing web based software. Here is a summary of how I write my applications in the context of a multi-tier architecture.

The presentation layer

In essence I'm a big fan of RIA (Rich Internet Application) for situations where I'm interested in developing a web based application as distinct from a web site full of HTML pages. I feel that this is a distinction lost on many people and I also think that those same people struggle with combining HTML/CSS/JS to make a web application.

I'm quite keen on developing something with Sproutcore as in a way, it blows away HTML and CSS and gives you the widgets to build a fully fledged MVC style app that works within the browser; its very similar to developing a native desktop application. The same can be said for Google Web Toolkit (GWT) however I slightly favour Sproutcore as it embraces JavaScript (JS) as a language whereas GWT embraces Java that produces JS i.e. Sproutcore "feels" lighter. Perhaps I should get over that... what Google have developed in the form of Google Wave is impressive.

There are other JS MVC frameworks out there (JavascriptMVC and PureMVC for starters), but I'm not sure that they drop HTML/CSS as a dependency for the developer to consider. I suppose what I'm feeling is that HTML and CSS do not belong in a web based application. Given HTML's start in life as a mark up language for documents I'm comfortable in acknowledging that it does not have a place in my web application.

The biggest thing for me right now with regards to JS RIA is the lack of development tooling. I've been using the Jetbrains WebStorm IDE for a couple months and while I'm impressed on its Window's implementation, it doesn't feel like a native Mac OS X application. Given that Mac OS X is where I like to spend a lot of my time this unfortunately creates a problem for me.

In my ideal world I'd be using Apache Maven for building and deploying my JS RIA's. I've really come to appreciate Maven in the Java space and it is just waiting for someone (may be even me!) to extend it for JS development (I'm familiar with JS Maven Tools but I understand that this project hasn't had activity for a long time). The pressures of family life and my daily job curtails the development of developer tools.

I shall pursue the use of SproutCore for my next RIA. So far I've just used HTML/CSS/JS and jQuery having implemented MVC in the raw. However when it comes to developing a website with perhaps a few dynamic requirements, may be I'll stay with trusty old JSP/Struts that communicates with my logic layer. When it comes to mobile and desktop, I will continue to do as the Romans do and develop native applications that communicate with my logic layer.

The logic layer

I've used Apache Camel on several projects now and just love it. What I end up with is a Java based application that can be managed as a service typically deployed to some brand of Unix. I've been using VMware's Hyperic to monitor the applications and given JMX I get some very deep monitoring capabilities.

I just love the Spring IoC framework and associated toolkits; particularly Spring JPA DAOs and Spring Test.

My applications tend to consist to lots of components that can exist independently of each other, and each with minimal dependencies on other frameworks and toolkits. For example, my application services containing the important business logic tend to be written as Java beans and have no or very little dependence on external libraries.

I lean towards creating RESTful services and look to leverage Apache CXF in this regard. I'm not yet using a toolkit to scaffold some of my RESTful DAO functionality but will at some point. I'm also a big fan of JSON as a payload format but XML's schema definitions have an important place in my heart. JSON with schemas would be a killer and I've just got to get into this.

Messaging is key and Active/MQ has been a great performer. I'm really looking forward to v.5.4 and its support of HTML 5 web sockets. This will allow messaging to be utilised by the JS RIA and I find that prospect quite exciting.

Apache Maven plays a huge role in developing and deploying my logic layer applications.

The data layer

I've been very happy with Postgres as a database and look forward to its forthcoming redundancy features. I'm also curious about Big table style approaches and Document Oriented Databases. I'm not quite sure why SQL should continue to play an application development standpoint (reporting, data mining etc. yes, but perhaps not within the application itself). ORMs have pushed me to the "NoSQL" conclusion and I like not having to deal with queries as much.

Summary

Multi-tier works for me. RIA appears to be the way of the future for web applications as distinct from web documents/pages. If you've not seen Apache Camel check it out. Postgres is great but I'm curious about Document Oriented Databases.

Please share your thoughts.

Friday, July 30, 2010

Development using Salesforce

I'm presently on a short contract developing using the Salesforce platform.

I've been using Salesforce for over 2 months now and I'm afraid to conclude that it doesn't make it as a viable platform for cloud application deployment. The reason for this is quite simple: it forces you to develop in the cloud as distinct from deploying to the cloud.

Salesforce thought that it would be great to re-invent the wheel, introduce a new language (Apex) and introduce the associated tooling. From a developer perspective this means that all of your regular tooling such as version control, continuos integration, deployment management, dependency management... I could go on... simply isn't there. Let me re-state a bit of that: no version control!

Developing on the Salesforce platform also means that you're dealing with 300ms (ish) round trips for every resource in their web development screens. This is because the platform is hosted in the US and the speed of light being what it is. A developer can quite commonly be waiting for several seconds while the development web app is doing its thing; reminds of my COBOL days 25 years ago when we had to submit stuff to a shared compiler resource and wait.

I'm quite turned on by the idea of deploying to the cloud and I think that VMforce and Google App Engine have chosen the right approach; they of course allow you to develop locally and then deploy to the cloud. Full scale application development in the cloud though is another thing and frankly Salesforce have got it wrong.

Friday, June 4, 2010

Invoking Maven and having it ignore your local settings

I recently found myself working remotely from my network and needed to perform a build using Maven. My ~/.m2/settings.xml file is configured with information about my network's Nexus repository and a few other things. I therefore needed to find a way to tell Maven to ignore my regular settings; preferably without mutating my settings.xml file. In particular I just wanted to have Maven pull out a plugin from the Central repo.

The documentation on the Maven command doesn't mention how it can be invoked to ignore your settings.xml. However if you type the following then it will ignore it (in my case I wanted to download the wonderful Cobertura plugin and produce a code coverage report) :

mvn -s/dev/null cobertura:cobertura

All good.

Wednesday, May 12, 2010

Flash on the iPhone

Given Steve Job's most recent letter concerning Flash on the iPhone, I'd like to broaden the debate to native plugins on the iPhone. Mr. Jobs provides a host of reasons why Flash is not permitted and it reminds me largely of his previous argument around needing native applications on the iPhone (remember that they encouraged us to create nice web apps instead at first; then there was the whole multi-tasking debate..).

There reaches a point with web applications where HTML, Javascript and CSS just can't do what you need them to do. These technologies have come an awful long way and HTML5 in particular is great. I spend a lot of time with these technologies and they are top of mind when considering new applications.

Let's take a concrete example of when you do require a plugin: Google Earth. Google Earth exists as a web plugin as well as a standalone executable. There are times when you'd like to embed Google Earth in a web page given its 3D capabilities; that's why the plugin exists of course!

Another example is with our own web plugin; it is something similar to Google Earth and has advanced capabilities with regards to map projections. We rely on third party C++ libraries and we utilise OpenGL.

Actually I think when it comes to 3D and the use of, say, OpenGL, web technologies fall short. There is a Mozilla proposal to expose OpenGL ES to Javascript, and that's great, but ES doesn't provide full OpenGL capability. Believe me, there are times when you need full OpenGL capability.

If I thought about it I'm sure there are other applications with dependencies such that you need to go native with a web plugin; not often perhaps, but we need to leave the native plugin door open for these situations.

I think Mr. Jobs has his reasons for not supporting Flash, but that's a separate consideration to supporting native web plugins.

In the end, I think that Adobe and Apple will come to an agreement and Adobe will release a well written and performant Flash plugin. The rest of us will then be able to install and write plugins for the iPhone when they are required.

Friday, April 16, 2010

Spring PropertyEditor for JSON map and array properties

I'm a big fan of Spring but found that it does not support map and list expressions in a property file to be substituted when using a PropertyPlaceholder. So I rolled my own PropertyEditor and can now express a map using JSON in my properties file e.g.:

myMapProperty ={"en-AU": "SKY", "ms": "SKY"}

Here's the property editor (depends on json-lib):

package <packagename>;

import java.beans.PropertyEditorSupport; 

import net.sf.json.JSON;
import net.sf.json.JSONSerializer;

/**
* Converts JSON expressions to Java arrays or maps and vice versa.
*
* @author huntc
*
*/
public class JSONPropertyEditor extends PropertyEditorSupport {

@Override
public String getAsText() {
Object object = getValue();
JSON jsonObject = JSONSerializer.toJSON(object);
return jsonObject.toString();
}

@Override
public void setAsText(String text) {
JSON json = JSONSerializer.toJSON(text);
setValue(json);
}
}

and here's what you must declare in your spring configuration xml:

<bean id="customEditorConfigurer"
class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Map">
<bean class="<packagename>.JSONPropertyEditor" />
</entry>
</map>
</property>
</bean>

The above indicates that for any required substitution of a map, use my property editor e.g.:

<bean id="someBeanWithAMapProperty"
class="someClass">
<property name="someMapProperty"
value="${myMapProperty}" />
</bean>

 

Tuesday, April 13, 2010

iPhone and multitasking

So here we are. Apple appears to be finally opening up the threading APIs to developers on the iPhone.

I've had numerous conversations with colleagues since the iPhone came out and they've been all sorts of reactions as to why there's no multithreading. Actually, now that I've just typed multithreading let's get this straight. Multitasking relates to the human experience of doing multiple things at the same time; it is a use-case; it is something that I've been told (by my wife) that men can't do and women can (!).

Multithreading is the ability for an OS to cooperatively or pre-emptively (generally the latter) slice processor time between different paths of execution within and outside of a number of processes (generally applications).

The iPhone has supported multitasking and multithreading forever. The difference now is that Apple appears to have opened up the multithreading API to non-Apple developers. I've not seen the details on this, perhaps they've constrained the thread APIs in some interesting way with the goal of limiting battery usage, but it is a very good (and necessary) thing that there will now be multithreading.

One application that I'm really looking forward to using is Skype. Finally, we'll be able to receive Skype calls with the same experience of receiving regular mobile calls; so long as you're on a WiFi network of course. I think that this will be amazing as I'm never near my computer when someone wants to contact me via Skype. However, I always have my iPhone at hand of course.

I can't wait for SIP supporting applications to come along for the iPhone either. The prospect of receiving my home phone calls when away from home via VOIP is fantastic.

Oh and one thing I'd like to joyfully throw back at the multithreading doubters: get over it. Yes, multithreaded programming is harder but its just the way the world is. Multiple things happen at the same time. Embrace it.

Well done Apple. I look forward to iPhone 4.0.

Monday, April 12, 2010

The pitfall of setting a list of parameters on a JQL query

I recently had a need to provide a collection as a parameter to a JQL IN expression. This is what I did:

List results = getJpaTemplate()
.find(
"from AbstractEvent e "
+ "where "
+ "(e.subscription, e.eventTime) in "
+ "(select e.subscription, max(e.eventTime) "
+ "from e "
+ "where "
+ "e.class in "
+ "(SentSMSFlightSubscribed,"
+ " ReceivedSMSFlightUnsubscribe) and "
+ "e.subscription.flightNo in (?) and "
+ "e.subscription.scheduled = ? "
+ "group by e.subscription)",
renderedFlight.getFlights(),
renderedFlight.getScheduled());

The problem with the query is that you get a class cast exception when an attempting to substitute the collection (renderedFlight.getFlights) .

To fix this you simply need to be explicit about the parameters:

    + "e.subscription.flightNo in (?1) and "
+ "e.subscription.scheduled = ?2 "

Problem solved.

Updated: Sunday 11 July 2010: Even using position parameters doesn't always work. While it works in the above example it didn't work for me when using a parameter of a non-primitive type; at least I think that was the issue. So in a nutshell, if the above doesn't work for you then just use findByNamedParams instead.

You may also note this beauty of a line:

e.class in (
SentSMSFlightSubscribed,
ReceivedSMSFlightUnsubscribe)

That is how you perform an "instanceof" style of operation in JQL. Nice.

 

Sunday, February 28, 2010

Java's Swing framework for Javascript and Canvas

It is 0051 on Sunday morning and I just had a wild thought...

I've been developing applications in Javascript using jQuery and taking an interest in Sproutcore. I love jQuery but most definitely subscribe to Sproutcore's architecture where it makes a very strong statement about web applications being distinct from web documents (there is a place for both).

...and then it occurred to me... why not try and implement Java's Swing framework in Javascript and use the Canvas element almost exclusively for web applications? Do away as much as possible with CSS and HTML - I don't think they're great for web applications anyhow...

I don't doubt that it'd be a lot of work implementing Swing in Javascript, but there's an awful lot of design to be leveraged there.

I think I'll sleep on it...

Wednesday, February 17, 2010

Does Grails lower the barriers of entry to programming?

Grails is the Groovy equivalent of Ruby on Rails and I've been working with Grails for the past couple of months.

I'm a big fan of programming by convention and adopted Apache Maven many moons ago for just this reason. Grails also promotes programming by convention and by and large its quite reasonable for building server hosted web applications.

However one thing in particular has been bothering me. It seems that there is a view that Grails saves you the trouble of worrying about what goes on underneath it. This attitude is similar to one where using ORMs such as Hibernate save you the need to understand databases.

These attitudes are fraught with dangers as has been beautifully pointed out by Joel Spolsky in his Leaky Abstractions article.

I would agree that Grails can assist in increasing productivity but not at the expense of knowing what goes on under the hood. As Joel puts it, "... the abstractions save us time working, but they don't save us time learning".

Today I came across a Grails situation where I compared a newly instantiated domain object with one obtained through GORM. From my perspective both objects were equivalent as they had the same identifiers. I had wrongly assumed though that GORM had adopted the Hibernate convention of providing hashCode() and equals() on a natural key. Because Grails does all this magic for me, I had just assumed that this would be done. Well, it doesn't; and that's fair enough; how would GORM know what the natural key is? (declaring the natural key could be a nice feature for GORM). The point is that I could quickly find the problem because I'm familiar with Java/JPA/Hibernate and know that hashCode() and equals() should be provided for natural keys.

My advice is to stay curious. Don't be content with copy and pasting a bit of code you found using Google, seeing it work but not understanding it. This situation will bite you on the bum when your product goes live and you get a problem that you can't diagnose because you don't really understand what the code is doing.

Programming computers is a complex business and that's a fact that should not be avoided. Embrace the complexity.

Saturday, February 13, 2010

Processing Javamail emails for specific mime types

I recently had to write some software that received an email and processed it for iCal events. I wanted my program to be tolerant of receiving the iCal events within the body or as a attachment. Furthermore if the attachment was a mail message then I wanted to look inside that email for the event and so on...

When I thought about the problem initially I thought that processing just the attachments of an email would be sufficient. That's not the case given Microsoft Outlook though. I quickly learnt that Outlook sends its iCal events within the body of an email and not as an attachment.

I ended up with the following bit of Javamail/iCal4j/Java code that should generally be useful for processing mail messages. In my case I'm looking for a text/calendar object but it could be anything of course. The addCalendarDataToCalendars function can be called recursively and adds any calendar objects it finds to the collection passed in. Enjoy.


/**
* Process a data handler's content looking for a
* calendar object.
*
* @param calendars
* the collection of calendars that we
* must add any found calendar to.
* @param dataHandler
* the data handler to use.
*/
private void addCalendarDataToCalendars(
Collection calendars,
DataHandler dataHandler) {
MimeType mimeType;
try {
mimeType =
new MimeType(dataHandler.getContentType());

if (mimeType.getBaseType()
.equals("text/calendar")) {
// Calendar data is what we're ultimately
// searching for.
CalendarBuilder builder =
new CalendarBuilder();
Calendar calendar = builder.build(
dataHandler.getInputStream());
calendars.add(calendar);

} else if (mimeType.getBaseType()
.equals("message/rfc822")) {
// Found an object representing an email
// address in its entirety.
Message mailMessage = (Message) dataHandler
.getContent();
addCalendarDataToCalendars(calendars,
mailMessage.getDataHandler());

} else if (mimeType.getBaseType()
.startsWith("multipart/")) {
// Found a bunch of attachments so
// process them each.
Multipart multipart =
(Multipart) dataHandler.getContent();
for (int i = 0, n = multipart.getCount();
i < n; ++i) {
Part part = multipart.getBodyPart(i);

String disposition =
part.getDisposition();

if ((disposition != null)
&& ((disposition.equals(Part.ATTACHMENT)
|| (disposition.equals(Part.INLINE))))) {
addCalendarDataToCalendars(calendars,
part.getDataHandler());

} else if (disposition == null) {
MimeBodyPart mimeBodyPart =
(MimeBodyPart) part;
addCalendarDataToCalendars(calendars,
mimeBodyPart.getDataHandler());

}
}
}

} catch (MimeTypeParseException e) {
logger
.warn("Ignoring attachment - could not " +
"parse the mime type of: "
+ dataHandler.getContentType()
+ " - " + e);
} catch (IOException e) {
logger.error(e);
} catch (ParserException e) {
logger
.warn("Ignoring attachment - could not " +
"interpret the calendar object: "
+ dataHandler.getName() + " - " + e);
} catch (MessagingException e) {
logger
.warn("Ignoring attachment - could not " +
"decode the calendar object: "
+ MimeUtility.getEncoding(dataHandler)
+ " - " + e);
}
}