Mashup the Enterprise: an example
This was originally posted on my dev2dev blog May 31st, 2007. Since that time Picasa albums have included a lot of Map features directly into the web application.
I recently attended the Dev2Dev Tech Days session in Chicago on May 16th. It was a very enjoyable session with a good showing of BEA developers in the Chicago area. If you missed the session, you can always download the slides. It got me thinking about my first mashup experience. It seems like everyone has the obligatory Google Maps demo, so I figured why not see what it would be like to do my own with some BEA tools like Workshop. It was pretty easy.
Here's the first pass showing my list of photo albums that is clickable and linked to the push pins on the map. Read on if you want to see how I built it.
For those of you that haven't heard of it, Picasa is a very handy image organization application for the desktop (Windows, Mac and Linux) that was acquired by Google some time ago. I'm a big fan and use it to organize all of my digital photos. They recently introduced a new feature that allows you to post an online version of your albums which are hosted for free by Google. Each album has meta data, such as the location it was taken, and I thought it would be be kind of cool to show the locations of my Picasa albums on a Google Map. Each user gets an RSS feed (here is mine) that contains all of their albums and the meta data.
In order to parse the RSS feed, I used Apache XML Beans. BEA Workshop makes it extremely easy to do XML to Java binding. For this example, I'm using BEA Workshop 9.2 MP1, but this should work equally well in 9.2 and 10. Workshop 8.1 also has XML Beans support, but you wouldn't be able to use the Java 5 features in your code.
- Create an EAR project - Pretty much just an empty container for the Web and Utility projects.
- Create a Dynamic Web project - in the wizard, check the checkbox to add this project to the EAR you just created.
- Create a Utility project - XML Beans support is enabled by default, but I added the facet for the XML Beans builder so my XSD's put in the schemas directory would auto-generate XML Beans, don't forget to associate this with the EAR as well.
- In the Utility project, add this RSS 2.0 XSD to the schemas directory, and the XML Beans classes should be automatically built. JTB EDIT 6/4/07 - I forgot to mention that I cleared out the targetNamespace and xmlns at the top of the schema to avoid an issue during parsing, namely that the PicasaWeb RSS feed doesn't include the Harvard namespace, so modify the schema to look like this at the top of the file: targetNamespace="" xmlns=""
- In the utility project, I created a simple java bean that will be used by the JSP for retrieving the information about my albums, and a simple class to parse the RSS URL into that bean. Here's an example of some of that quick and dirty code.
1: //http://picasaweb.google.com/data/feed/base/user/jambay?category=album&alt=rss&hl=en_US&access=public
2: URL url = new URL(sRSS_URL);
3:
4: //make the url connection and parse the results into the xml bean
5: URLConnection urlConnection = url.openConnection();
6: urlConnection.connect();
7:
8: //this is one of the autogenerated classes that we get for free
9: //just by dropping in the xsd to the schemas directory
10: RssDocument rssDoc = RssDocument.Factory.parse( urlConnection.getInputStream() );
11:
12: //get the generic info about the title, number of albums, etc
13: XmlObject o = rssDoc.getRss().getChannel().getTitle();
14: XmlCursor c = o.newCursor();
15: title = c.getTextValue();
16: _log.debug( c.getTextValue() );
17:
18: List<Item> items = rssDoc.getRss().getChannel().getItemList();
19:
20: _log.debug( "There are " + items.size() + " albums" );
21: numberOLocations = items.size();I think you get the idea. So now all that's left to do is to put these locations on a map. Google has some very easy instructions on their map API. Sign up for an API key (or just use one for localhost:7001) and start by turning their most basic example into a JSP. Here's the beginning of mine. Notice that I use Apache Commons for escaping java script, this is necessary for the html that pops up when clicking on the push pins.
1: <%@ page language="java" contentType="text/html;charset=UTF-8" import="org.apache.commons.lang.StringEscapeUtils, google.maps.bean.IGoogleMapsBean, google.maps.bean.PicasaRSSBean"%>
2:
3: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
4: "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
5:
6: <%1:2:3: String defaultRssLink = "http://picasaweb.google.com/data/feed/base/user/jambay?category=album&alt=rss&hl=en_US&access=public";4: PicasaRSSBean picasaRssBean = new PicasaRSSBean();5:6: String rssLink = request.getParameter( "rssLink" );7: if( rssLink == null || ("").equals( rssLink.trim() ) )8: rssLink = defaultRssLink;9:10: picasaRssBean.initializePicasaRSS( rssLink );11:12: IGoogleMapsBean googleBean = picasaRssBean;%>
7:
8: <html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
9: <head>
10: <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
11: <title><% 1: = googleBean.getTitle() %></title>
12:
13: <style type="text/css">
14: v\:* {
15: behavior:url(#default#VML);
16: }
17: </style>
18:
19: <!-- this is the localhost:7001 Google Maps API key -->
20: <script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAA71qM4JtJh0mbvp5L8wvSSBRMlDO_sAYUHpd58UCyQxfNbq8wexS4U_-xDC1v8-rYvsV4XJbSKCsGJw"
21: type="text/javascript"></script>
There are some other java script functions that you'll need to do everything, I'll post the full example to codeshare, But essentially it involves Geocoding using some Google provided js functions, which puts a push pin on the map for each location. So in the screen shot below, when the push pin or link is clicked, the map is centered on that location and the html preview of the album shows in a balloon. Let me know what you think.