<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type='text/xsl' href='http://auburnmarshes.spaces.live.com/mmm2008-07-24_12.50/rsspretty.aspx?rssquery=en-US;http%3a%2f%2fauburnmarshes.spaces.live.com%2fcategory%2fMashups%2ffeed.rss' version='1.0'?><rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:msn="http://schemas.microsoft.com/msn/spaces/2005/rss" xmlns:live="http://schemas.microsoft.com/live/spaces/2006/rss" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Design by Committee: Mashups</title><description /><link>http://auburnmarshes.spaces.live.com/?_c11_BlogPart_BlogPart=blogview&amp;_c=BlogPart&amp;partqs=catMashups</link><language>en-US</language><pubDate>Thu, 28 Aug 2008 00:34:01 GMT</pubDate><lastBuildDate>Thu, 28 Aug 2008 00:34:01 GMT</lastBuildDate><generator>Microsoft Spaces v1.1</generator><docs>http://www.rssboard.org/rss-specification</docs><ttl>60</ttl><cf:parentRSS>http://auburnmarshes.spaces.live.com/blog/feed.rss</cf:parentRSS><live:type>blogcategory</live:type><live:identity><live:id>1123747515435059140</live:id><live:alias>auburnmarshes</live:alias></live:identity><cf:listinfo><cf:group ns="http://schemas.microsoft.com/live/spaces/2006/rss" element="typelabel" label="Type" /><cf:group ns="http://schemas.microsoft.com/live/spaces/2006/rss" element="tag" label="Tag" /><cf:group element="category" label="Category" /><cf:sort element="pubDate" label="Date" data-type="date" default="true" /><cf:sort element="title" label="Title" data-type="string" /><cf:sort ns="http://purl.org/rss/1.0/modules/slash/" element="comments" label="Comments" data-type="number" /></cf:listinfo><item><title>WSO2 Mashup Server heap space fix</title><link>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!870.entry</link><description>&lt;p&gt;Thanks for Tyrell for finally locating the source of the elusive Java heap space error, which I came across sporadically during my daily Mashup Server stress testing.  Tyrell describes the fix that you can add to your 1.5.1 installation &lt;strong&gt;&lt;a href="http://tyrellperera.blogspot.com/2008/08/increasing-memory-allocated-to-wso2.html"&gt;here&lt;/a&gt;&lt;/strong&gt;.&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=1123747515435059140&amp;page=RSS%3a+WSO2+Mashup+Server+heap+space+fix&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=auburnmarshes.spaces.live.com&amp;amp;GT1=auburnmarshes"&gt;</description><comments>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!870.entry#comment</comments><guid isPermaLink="true">http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!870.entry</guid><pubDate>Mon, 25 Aug 2008 19:35:50 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://auburnmarshes.spaces.live.com/blog/cns!F985A6952BC07C4!870/comments/feed.rss</wfw:commentRss><wfw:comment>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!870.entry#comment</wfw:comment><dcterms:modified>2008-08-25T19:36:13Z</dcterms:modified></item><item><title>"Why SOA Architects Should Care" about Enterprise Mashups</title><link>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!860.entry</link><description>&lt;p&gt;Can't help but repeat a few choice bits from a recent article &lt;a href="http://www.soamag.com/I21/0808-1.asp"&gt;&lt;strong&gt;Enterprise Mashups Part II: Why SOA Architects Should Care&lt;/strong&gt;&lt;/a&gt; by Chris Warner and John Crupi.  Too bad I didn't see this before the &lt;strong&gt;&lt;a href="http://auburnmarshes.spaces.live.com/blog/cns!F985A6952BC07C4!854.entry"&gt;Enterprise Capabilities of the WSO2 Mashup Server 1.5 webinar&lt;/a&gt;&lt;/strong&gt; I gave this morning - I could have cribbed a few bits of wisdom! Like these: &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;Mashups bring a “user” into the SOA mix. ... By having the business build mashups upon the foundation of your service-oriented architecture, they essentially become SOA champions without knowing it.&lt;/em&gt; &lt;/blockquote&gt; &lt;p&gt;This is a point we tried to hit strongly in the &lt;strong&gt;&lt;a href="http://wso2.org/projects/mashup"&gt;WSO2 Mashup Server&lt;/a&gt;&lt;/strong&gt;, which can help bring individuals, teams, or enterprises together into a community around services, and strengthen the concept of a &amp;quot;user&amp;quot; and help build a diverse set of user experiences tied to services.  Until the SOA platform gets connected to the business users, the promises of SOA (business agility) won't be fully realized. &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;In addition to SOA-friendly formats, such as RSS and Atom plus REST and SOAP, mashup creators can publish mashups to spreadsheets, as WSRP-compliant portlets, wiki- and blog-friendly widgets, or even into a mobile phone as a micro-application. &lt;u&gt;Mashups can become the vehicle through which services become part of the everyday tools of the enterprise business user.&lt;/u&gt;&lt;/em&gt;&lt;/blockquote&gt; &lt;p&gt;Which is why we've added on to the RSS, Atom, REST, and SOAP support in 1.0 the ability to interact with spreadsheets and databases (through Data Services), and are starting our foray into the world of portlets, widgets, and gadgets with support for Google gadgets. &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;&lt;u&gt;Mashups can go well beyond leveraging an SOA by becoming part of that SOA, allowing developers to create customized “service skins” from core services.&lt;/u&gt; ...&lt;/em&gt; &lt;p&gt;&lt;em&gt;Because mashups can be exposed as REST-, WSDL- and JSON-based services, they look and feel like a real SOA-based service to developers who want to consume them. ... &lt;/em&gt;&lt;em&gt;The mashup, created by the developer, becomes the tailored service which is directly aligned with their particular need. Major enhancements to core services can be accommodated with a reformulated or updated mashup by the mashup creators themselves. &lt;/em&gt;&lt;/blockquote&gt; &lt;p&gt;Yes, we've found our users (and ourselves) using the WSO2 Mashup Server for more than just combining services into a new one, but for rapid development of new services, or for customizing services to a particular scenario.  From the outside, these don't just look like real services - they are real services - for example in the 1.5 release high levels of security can be applied to the services even though they are so easy to write.  A good example of a &amp;quot;skinned&amp;quot; service - the &lt;strong&gt;&lt;a href="http://mooshup.com/mashup.jsp?path=/mashups/system/digit2image"&gt;digit2image&lt;/a&gt;&lt;/strong&gt; sample service that comes with the mashup server tailors a very general purpose and complicated service (&lt;strong&gt;&lt;a href="http://www.flickr.com/services/api/"&gt;Flickr&lt;/a&gt;&lt;/strong&gt;) for a particular narrow purpose - to find a random image, with appropriate copyright, for a single numeric digit.  By providing a narrow API, this capability can be exposed more easily and efficiently (some caching is performed by the service to speed up returns).  And it allows innovation without touching the original Flickr service which we don't have control over.  For instance, I could search beyond Flickr for appropriate images without breaking the service contract or rewriting the Flickr service. &lt;p&gt;Toward the end, the authors write: &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;At this point &lt;u&gt;any SOA architect worth his WSDL should see that mashups can greatly enhance an SOA and don’t necessarily ignore or break the principles that made your SOA great.&lt;/u&gt; But governance, granularity and scope for mashups do require subtle tweaks and adjustments to your enterprise toolset.&lt;/em&gt;&lt;/blockquote&gt; &lt;p&gt;Indeed, governance is important as your SOA grows and chaos theory has a chance to get a toehold.  The WSO2 Mashup Server is taking the first steps into governance by relying on the &lt;strong&gt;&lt;a href="http://wso2.org/projects/registry"&gt;WSO2 Registry&lt;/a&gt;&lt;/strong&gt; to store mashups in a versioned repository, manage ownership, users and roles, and facilitate communication and the building of trust in an Enterprise SOA community.  But we still have to to a better job of working with the Registry's features for supporting multiple versions, product lifecycles, and dependency management.  For instance, while the Mashup Server stores all it's mashups, comments, tags, ratings, etc. in the Registry, when you deploy a new mashup, it doesn't automatically populate the registry with the WSDL.  We're looking at much better integration with the Registry as a primary feature of our next Mashup Server release. &lt;p&gt;Kudos to the authors for clearly presenting not just the case for service mashups in an SOA architecture, but why any SOA architecture that doesn't expand into the mashup space is missing out on huge opportunities. &lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=1123747515435059140&amp;page=RSS%3a+%22Why+SOA+Architects+Should+Care%22+about+Enterprise+Mashups&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=auburnmarshes.spaces.live.com&amp;amp;GT1=auburnmarshes"&gt;</description><comments>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!860.entry#comment</comments><guid isPermaLink="true">http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!860.entry</guid><pubDate>Tue, 12 Aug 2008 21:25:21 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://auburnmarshes.spaces.live.com/blog/cns!F985A6952BC07C4!860/comments/feed.rss</wfw:commentRss><wfw:comment>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!860.entry#comment</wfw:comment><dcterms:modified>2008-08-12T21:25:21Z</dcterms:modified></item><item><title>WSO2 Mashup Server 1.5 released!</title><link>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!848.entry</link><description>&lt;p&gt;&lt;a href="http://byfiles.storage.msn.com/y1p__3wV1rLjo9SnIoWSu6N4POJ59py7boin35hnSUlQKukr9LAvnzfcL9ygBvq_zd1LsnXI5X5rdw?PARTNER=WRITER"&gt;&lt;img style="margin:0px 25px 0px 0px" height=110 alt=pulsecutaway src="http://byfiles.storage.msn.com/y1p0d7nAQXpyvxjBLvpKEeS03NItI08PbAfGMRJjeezbS_sofQSpNaSCv39qWlp3xmdjQbB2YH4D60?PARTNER=WRITER" width=109 align=left&gt;&lt;/a&gt; I'm proud to say that v1.5 of the WSO2 Mashup Server is now available for &lt;strong&gt;&lt;a href="http://wso2.org/downloads/mashup/"&gt;download&lt;/a&gt;&lt;/strong&gt;!  This release has been a few months in the making, and I'm thrilled to see a major update to the Mashup Server finally out.  News release &lt;strong&gt;&lt;a href="http://wso2.com/about/news/mashup-1-5-release/"&gt;here&lt;/a&gt;&lt;/strong&gt;.   &lt;p&gt;Thanks to the efforts of &lt;strong&gt;&lt;a href="http://www.keith-chapman.org/"&gt;Keith&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href="http://tyrellperera.blogspot.com/"&gt;Tyrell&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href="http://channa.gunawardena.org/"&gt;Channa&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href="http://yumani.blogspot.com/"&gt;Yumani&lt;/a&gt;&lt;/strong&gt;, and many others at &lt;strong&gt;&lt;a href="http://wso2.com"&gt;WSO2&lt;/a&gt;&lt;/strong&gt;, we've been able to put some snazzy new features in this release: &lt;ul&gt; &lt;li&gt;Integrated &lt;strong&gt;&lt;a href="http://wso2.com/about/news/wsas-searchsoa-gold-award-2008/"&gt;award-winning&lt;/a&gt;&lt;/strong&gt; Data Services: quickly and with zero-coding map queries on your databases, Excel spreadsheets, or CSV files into Web services. &lt;li&gt;Google Gadgets: power a Google gadget with a mashup service - we generate a try-it, a code template for customizing the gadget, and even a build in Gadget dashboard based on &lt;strong&gt;&lt;a href="http://incubator.apache.org/shindig/"&gt;Apache Shindig&lt;/a&gt;&lt;/strong&gt;. &lt;li&gt;Security, security, security: Limit access to your mashup service to only authorized users, encrypt and sign your messages, and access services which are secured.  I think our security interface is the easiest way to engage advanced WS-Security features that's out there! &lt;li&gt;&lt;strong&gt;&lt;a href="http://openid.org/"&gt;OpenID&lt;/a&gt;&lt;/strong&gt; login support.&lt;/ul&gt; &lt;p&gt;There's lots of little improvements too, and I hope to talk about those, as well as the major features above, in upcoming posts. &lt;p&gt;For now though, a hearty congratulations and a good night's sleep to the Mashup Server team!&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=1123747515435059140&amp;page=RSS%3a+WSO2+Mashup+Server+1.5+released!&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=auburnmarshes.spaces.live.com&amp;amp;GT1=auburnmarshes"&gt;</description><comments>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!848.entry#comment</comments><guid isPermaLink="true">http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!848.entry</guid><pubDate>Mon, 21 Jul 2008 16:18:59 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://auburnmarshes.spaces.live.com/blog/cns!F985A6952BC07C4!848/comments/feed.rss</wfw:commentRss><wfw:comment>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!848.entry#comment</wfw:comment><dcterms:modified>2008-07-21T16:18:59Z</dcterms:modified></item><item><title>A scraping incident</title><link>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!813.entry</link><description>&lt;p&gt;One of my mashups fell prey to the dreaded scrape rot - a complete overhaul of the target site that invalidated all of my scraping rules.  The pages in question are from &lt;strong&gt;&lt;a href="http://globalincidendmap.com"&gt;globalincidendmap.com&lt;/a&gt;&lt;/strong&gt;, which previously powered my &lt;strong&gt;&lt;a href="https://mooshup.com/mashup.jsp?path=/mashups/jonathan/internationalincident"&gt;internationalincident&lt;/a&gt;&lt;/strong&gt; mashup (see &lt;strong&gt;&lt;a href="http://auburnmarshes.spaces.live.com/blog/cns!F985A6952BC07C4!768.entry"&gt;Sri Lanka Incident Mashup&lt;/a&gt;&lt;/strong&gt;).  The change was catastrophic - queryable content from the site is no longer free, but requires a paid membership and a login process.  One option would be to pay for a membership, but besides the steep price I doubt that the license terms allow republishing of the data.  I could support the mashup only for paid users of the service, collecting credentials and forwarding them on, but that again is both questionably secure (a user would have to trust that I didn't abuse the credentials temporarily in my possession), and unrealistic since few if any of my audience would spring for the cost of membership.  In effect, my mashup has been totaled. &lt;p&gt;This illustrates one reason why scraping should be used only as a last resort, when no more stable forms of content are available - feeds or Web services.  When you mix the content and presentation, changes in the presentation are easily confused with changes in the content.  Although the scraping features of the &lt;a href="http://wso2.org/projects/mashup"&gt;&lt;strong&gt;WSO2 Mashup Server&lt;/strong&gt;&lt;/a&gt; are popular, I like to think of them as a stop-gap while publishers find cost-effective ways of serving up presentation-free content, such as delivering simple services using the Mashup Server ;-).  Ideally, more and more publishers will recognize the value of raw content, and the need for Web scraping will diminish.  Gonna take a while though... &lt;p&gt;Even without scraping, there remains one of the deep problems with mashups and distributed programming, that of services that disappear, are altered, change usage terms, etc., breaking their dependent mashups in the process.  There has been lots written on this, which can be generally summed up as &amp;quot;this is a hard problem.&amp;quot; &lt;p&gt;One thing we plan to do in the future to make sure that service changes don't harm downstream dependents is use more of the advanced functionality of the &lt;strong&gt;&lt;a href="http://wso2.org/project/registry"&gt;WSO2 Registry&lt;/a&gt;&lt;/strong&gt; upon which the &lt;strong&gt;&lt;a href="http://wso2.org/projects/mashup"&gt;WSO2 Mashup Server&lt;/a&gt;&lt;/strong&gt; is built - namely, versioning.  Today, each time a service changes, an old copy is retained in the database, but no longer is &amp;quot;alive&amp;quot; as a service.  Some future version will have a simple interface for continuing to keep the old versions online, and help users to lock into one of these previous versions.  Some cool dependency management features on the drawing board for the Registry will also help find and record dependencies and notify dependents of changes. &lt;p&gt;But would these help in the case of the internationalincident service?  This is a case where there is a deliberate change which prevents &amp;quot;unauthorized&amp;quot; access.  The solution in this case was to mark the service as obsolete, and go out and find a whole new source of data.  The new &lt;strong&gt;&lt;a href="https://mooshup.com/services/jonathan/srilankanincident/"&gt;srilankanincident&lt;/a&gt;&lt;/strong&gt; service is a result - though the data is slightly different, perhaps a result of focusing narrowly on Colombo, it was a fairly short task to reprogram it, and even improve it, once I had found a new source of data.  The speed of fixing catastrophic failures is my current best hope against scrape rot.&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=1123747515435059140&amp;page=RSS%3a+A+scraping+incident&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=auburnmarshes.spaces.live.com&amp;amp;GT1=auburnmarshes"&gt;</description><comments>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!813.entry#comment</comments><guid isPermaLink="true">http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!813.entry</guid><pubDate>Tue, 27 May 2008 16:40:41 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://auburnmarshes.spaces.live.com/blog/cns!F985A6952BC07C4!813/comments/feed.rss</wfw:commentRss><wfw:comment>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!813.entry#comment</wfw:comment><dcterms:modified>2008-05-27T16:45:41Z</dcterms:modified></item><item><title>Mashup Server Webinar May 13th</title><link>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!811.entry</link><description>&lt;p&gt;I've got another free Webinar coming up - again an Introduction to the WSO2 Mashup Server and to &lt;a href="http://mooshup.com"&gt;&lt;strong&gt;mooshup.com&lt;/strong&gt;&lt;/a&gt; on 13 May from 9-10AM PST.  Join me if you:  &lt;li&gt;Are curious about mashups, Mashup Server products, and want an overview of the capabilities of WSO2's offering.  &lt;li&gt;Have services, web pages, or other information sources available but you want smarter ways to use those services.  &lt;li&gt;Always wanted an application to do (x) on the Web but it was always too costly to develop.  &lt;li&gt;Know Javascript and want to see what it can do outside the browser. &lt;p&gt;&lt;strong&gt;&lt;a href="https://wso2.on.intercall.com/confmgr/event_description.jsp?title=Introducing+the+WSO2+Mashup+Server&amp;amp;type=regrequired&amp;amp;eventid=65382"&gt;Register now!&lt;/a&gt;&lt;/strong&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=1123747515435059140&amp;page=RSS%3a+Mashup+Server+Webinar+May+13th&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=auburnmarshes.spaces.live.com&amp;amp;GT1=auburnmarshes"&gt;</description><comments>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!811.entry#comment</comments><guid isPermaLink="true">http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!811.entry</guid><pubDate>Fri, 09 May 2008 14:20:11 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://auburnmarshes.spaces.live.com/blog/cns!F985A6952BC07C4!811/comments/feed.rss</wfw:commentRss><wfw:comment>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!811.entry#comment</wfw:comment><dcterms:modified>2008-05-09T14:56:59Z</dcterms:modified></item><item><title>Webinar - A New Approach to Web Service Composition</title><link>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!774.entry</link><description>&lt;p&gt;I'm giving a free Webinar on 15 April 2008 9-10AM PDT about the approach we took to service composition in the WSO2 SOA Platform.  Instead of a declarative approach which my XSLT days showed can be powerful yet also limiting in many ways compared with a full programming language, the &lt;strong&gt;&lt;a href="http://wso2.org/projects/mashup" target="_blank"&gt;WSO2 Mashup Server&lt;/a&gt;&lt;/strong&gt; uses a &amp;quot;scriptable Web Services&amp;quot; metaphor, and supports the ability to consume and produce Web Services using simple Javascript expressions.  Add to that the ability to script non-Web Service materials like Web pages and feeds, and you've got a powerful yet accessible platform for creating Web Service mashups.  &lt;strong&gt;&lt;a href="https://wso2.on.intercall.com/confmgr/event_description.jsp?title=A+New+Approach+to+Service+Composition+-+the+WSO2+Mashup+Server&amp;amp;type=registered&amp;amp;eventid=63656" target="_blank"&gt;Register now!&lt;/a&gt;&lt;/strong&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=1123747515435059140&amp;page=RSS%3a+Webinar+-+A+New+Approach+to+Web+Service+Composition&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=auburnmarshes.spaces.live.com&amp;amp;GT1=auburnmarshes"&gt;</description><comments>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!774.entry#comment</comments><guid isPermaLink="true">http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!774.entry</guid><pubDate>Tue, 08 Apr 2008 20:01:17 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://auburnmarshes.spaces.live.com/blog/cns!F985A6952BC07C4!774/comments/feed.rss</wfw:commentRss><wfw:comment>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!774.entry#comment</wfw:comment><dcterms:modified>2008-04-08T20:02:20Z</dcterms:modified></item><item><title>Sri Lankan Incident Mashup</title><link>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!768.entry</link><description>&lt;p&gt;I just posted a finished version of a Mashup designed to help answer the question &amp;quot;is &lt;em&gt;Sri Lanka getting safer or not?&lt;/em&gt;&amp;quot;  This is a question we on the global WSO2 team ask each time we arrange travel to that unfortunately troubled country.  Despite a spate of violence early this year, designed to coincide with the formal dissolution of the cease fire that has done little to prevent violence, it seemed to me things were getting a little better.  But I needed some facts to back that up. 
&lt;p&gt;&lt;a href="http://byfiles.storage.msn.com/y1pmtDZPjRCMHnfXHyc5oSJhnWNevE1GGxodg-sdkxTWRXUWCbaVQqA_y4WWizgTh-AJ5wm5ITYAik?PARTNER=WRITER"&gt;&lt;img style="margin:0px 0px 0px 10px" height=210 alt=image src="http://byfiles.storage.msn.com/y1pmtDZPjRCMHkBp6OjtWuVuO6KXPbZKmRwHRHP0S3Q-CveR7Lhl7xyhSAwBzi3UfUFRwd3GPpEOYM?PARTNER=WRITER" width=135 align=right&gt;&lt;/a&gt; The mashup plots bombings and other incidents as a bar chart, measuring the severity of the incident (how many killed &amp;amp; wounded) over the last 18 months.  The idea was to see if there was a clear overall trend in the violence or not, something not readily apparent from a Google map (see right). 
&lt;p&gt;The mashup service itself consists of several items, each one a simple task accomplished in half a page of javascript: 
&lt;ul&gt;
&lt;li&gt;Scrape the search results page at &lt;strong&gt;&lt;a href="http://globalincidentmap.com/"&gt;globalincidentmap.com&lt;/a&gt;&lt;/strong&gt; to pull the essential data out of an HTML table for the country of interest, and put it into a simple XML structure. 
&lt;li&gt;Cache the page if it has already been accessed within 24 hours (scraping is expensive, the first access in any 24 hour period will be pretty slow.) 
&lt;li&gt;Parse the headline for patterns such as &amp;quot;eight killed&amp;quot; or &amp;quot;injures 7&amp;quot; and turn that into killed and wounded digits (this isn't perfect, but we can tolerate a few errors since we're trying to present an overall sense of the problem rather than perfectly accurate statistics.)  Also filter out as much as possible the killing of LTTE, as that's more a measure of war than of terrorism. 
&lt;li&gt;Provide a helper method to look up details and get a link to a new story for any item.&lt;/ul&gt;
&lt;p&gt;Using this service (called &lt;strong&gt;&lt;a href="https://mooshup.com/mashup.jsp?path=/mashups/jonathan/internationalincident"&gt;internationalindicent&lt;/a&gt;&lt;/strong&gt;) I created a custom HTML UI to format Sri Lanka-specific results into the bar chart and to make it interactive (click on a bar to see more info about the incident.)  Then I used &amp;quot;share this mashup&amp;quot; to upload the service to &lt;strong&gt;&lt;a href="http://mooshup.com/"&gt;mooshup.com&lt;/a&gt;&lt;/strong&gt; so others could try it out (or copy the code.) 
&lt;p&gt;The rough version took a couple of hours, mostly figuring out the details of scraping the page and coming up with the headline patterns to look for, but then I spent a couple more polishing the HTML UI so I wouldn't be embarrassed to share it.  In the process I demonstrated some of the powerful aspects of using mashup technologies in your development arsenal: 
&lt;ul&gt;
&lt;li&gt;Instead of investigating the current situation using Google News for 30-60 minutes each time we plan a trip for the latest information, I can browse this site in a few minutes, see the trend, and get details of any recent incidents I'm interested in.  This will pay for itself in terms of my own personal productivity before long. 
&lt;li&gt;There is also a small user group (really, just the handful of WSO2 employees based outside Sri Lanka) who can also benefit from this micro-application, increasing their productivity as well. 
&lt;li&gt;The &lt;strong&gt;&lt;a href="http://wso2.org/projects/mashup"&gt;WSO2 Mashup Server&lt;/a&gt;&lt;/strong&gt; makes the data available as a service, so others can reuse it too, for alternate displays or to generate displays for other parts of the world. 
&lt;li&gt;And, it's just fun!&lt;/ul&gt;
&lt;p&gt;So ... is Sri Lanka getting safer?  I'll have to let you be the judge of that.  Go to &lt;strong&gt;&lt;a title="https://mooshup.com/services/jonathan/internationalincident/" href="http://mooshup.com/services/jonathan/internationalincident/"&gt;http://mooshup.com/services/jonathan/internationalincident/&lt;/a&gt;&lt;/strong&gt; to see for yourself!
&lt;p&gt;&lt;em&gt;[Update 5/27: This service is no longer available.  See &lt;/em&gt;&lt;a href="http://auburnmarshes.spaces.live.com/blog/cns!F985A6952BC07C4!813.entry"&gt;&lt;strong&gt;&lt;em&gt;http://auburnmarshes.spaces.live.com/blog/cns!F985A6952BC07C4!813.entry&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;em&gt; for more info.]&lt;/em&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=1123747515435059140&amp;page=RSS%3a+Sri+Lankan+Incident+Mashup&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=auburnmarshes.spaces.live.com&amp;amp;GT1=auburnmarshes"&gt;</description><comments>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!768.entry#comment</comments><guid isPermaLink="true">http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!768.entry</guid><pubDate>Tue, 01 Apr 2008 00:37:06 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://auburnmarshes.spaces.live.com/blog/cns!F985A6952BC07C4!768/comments/feed.rss</wfw:commentRss><wfw:comment>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!768.entry#comment</wfw:comment><dcterms:modified>2008-05-27T16:45:34Z</dcterms:modified></item><item><title>Mashup Camp 6</title><link>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!764.entry</link><description>&lt;a href="http://mashupcamp.com/"&gt;&lt;/a&gt; &lt;p&gt;&lt;a title="20080319-_ND32514" href="http://www.flickr.com/photos/7824314@N08/2351047672/"&gt;&lt;img alt="20080319-_ND32514" hspace=6 src="http://static.flickr.com/2369/2351047672_bfcd16eb39_m.jpg" align=right border=0&gt;&lt;/a&gt;Just returned from some travel which included 2 days of Mashup University and a day of &lt;strong&gt;&lt;a href="http://mashupcamp.com/"&gt;Mashup Camp&lt;/a&gt;&lt;/strong&gt;.  A few thoughts: &lt;ul&gt; &lt;li&gt;Maps are still well represented.  This surprised me a bit, but I recognize I've been well immersed in the &lt;strong&gt;&lt;a href="http://wso2.org/projects/mashup"&gt;WSO2 Mashup Server&lt;/a&gt;&lt;/strong&gt; which supports a wide variety of User Interactions (html pages including maps, but also feeds, email, instant messaging.)  I predict non-map mashups will start to eat into the map-based mashup market share dominance over the next year. &lt;li&gt;There's lots of interest in consuming various Web APIs.  Some vendors were promoting their APIs, others tools for consuming those APIs.  I think the WSO2 Mashup Server can tap into an underserved market here, since it's the easiest way I know of to deliver a comprehensive Web API on top of a bit of Javascript logic, which in turn can front information sources as diverse as databases and scraped web pages.  I think the Mashup Server can become a &amp;quot;design your own API&amp;quot; tool that can have great appeal to the mashup developer. &lt;li&gt;A lot of Javascript was in evidence, further validating our choice to use Javascript for mashup logic in the WSO2 Mashup Server. &lt;li&gt;For the first time I ran into a few people with serious interest in &lt;a href="https://wadl.dev.java.net/wadl20061109.pdf"&gt;&lt;strong&gt;WADL&lt;/strong&gt;&lt;/a&gt;.  Has its time finally come?  More on that in a subsequent post. &lt;li&gt;The &amp;quot;&lt;strong&gt;&lt;a href="http://wiki.mashupcamp.com/index.php/AboutMashupCamp#What_is_an_unconference.3F"&gt;unconference&lt;/a&gt;&lt;/strong&gt;&amp;quot; style was quite interesting and successful, especially if you're like me and are more interesting in connecting with interesting individuals than in hearing yet another vendor pitch (mine excepted of course!) ;-)  One thing that is sorely lacking is any kind of organization to the conference &lt;strong&gt;&lt;a href="http://wiki.mashupcamp.com/index.php/MashupWikiHome"&gt;Wiki&lt;/a&gt;&lt;/strong&gt;, and a surprising lack of ability to record much of the activity there.  I couldn't even find who won the Best Mashup contest...&lt;/ul&gt; &lt;p&gt;I can't wait till next year!&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=1123747515435059140&amp;page=RSS%3a+Mashup+Camp+6&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=auburnmarshes.spaces.live.com&amp;amp;GT1=auburnmarshes"&gt;</description><comments>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!764.entry#comment</comments><guid isPermaLink="true">http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!764.entry</guid><pubDate>Tue, 25 Mar 2008 18:31:52 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://auburnmarshes.spaces.live.com/blog/cns!F985A6952BC07C4!764/comments/feed.rss</wfw:commentRss><wfw:comment>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!764.entry#comment</wfw:comment><dcterms:modified>2008-03-25T18:31:52Z</dcterms:modified></item><item><title>Mashing up a National Geographic Photo of the Day Feed</title><link>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!714.entry</link><description>&lt;p&gt;(This article &lt;strong&gt;&lt;a href="http://wso2.org/library/2760"&gt;first appeared&lt;/a&gt;&lt;/strong&gt; a few days ago on the &lt;strong&gt;&lt;a href="http://wso2.org/"&gt;WSO2 Oxygen Tank&lt;/a&gt;&lt;/strong&gt;.) 
&lt;p&gt;I recently wrote a neat little mashup which demonstrates a little of the power of the &lt;strong&gt;&lt;a href="http://wso2.org/projects/mashup"&gt;WSO2 Mashup Server&lt;/a&gt;&lt;/strong&gt; to flow information from one place to another, and from one format to another.  I had a simple set of requirements: 
&lt;ol&gt;
&lt;li&gt;I use the &lt;strong&gt;&lt;a href="http://pack.google.com/"&gt;Google Photos Screensaver&lt;/a&gt;&lt;/strong&gt; to show a slideshow of interesting photographs when the family-room computer isn’t being used.  Since the family room computer includes the 37-inch LCD screen as a separate monitor, high quality photos come out really clear and make for a nice, constantly changing design element for the room.  It works best if the set of photographs changes before it gets old. 
&lt;li&gt;I recently found the National Geographic site’s “&lt;strong&gt;&lt;a href="http://photography.nationalgeographic.com/photography/photo-of-the-day/"&gt;photo of the day&lt;/a&gt;&lt;/strong&gt;” section as an interesting source of high-quality photographs that updates on a daily basis.  However, National Geographic doesn’t provide a feed for the photo of the day. &lt;/ol&gt;
&lt;p&gt;Essentially then the task was to scrape the URLs from the photo of the day, and package them into a feed.  The complication comes from the fact that there doesn’t seem to be a list of photos of the day available on the National Geographic web site – just links from a particular photo to the one for the previous (or next) day.  Because a feed of 30 photos requires 30 different pages to be scraped, some caching really becomes necessary to improve performance, especially since feed readers can be expected to bombard the service if it proves popular. 
&lt;p&gt;I initially broke down the task into three parts: 
&lt;ol&gt;
&lt;li&gt;Scraping a photo of the day page to extract the useful metadata, including the date, title, photographer’s credit, and description of the photo, a set of links to the actual image in various sizes, and links to the page being scraped (so one can return there easily) and to the previous page in the photo stream.  Since this metadata shouldn’t vary, cache it locally for faster retrieval. 
&lt;li&gt;Searching the cache or going to the web site (and thus populate the cache) to acquire the metadata for a particular date. 
&lt;li&gt;Formatting the metadata for a particular range of dates into a feed. &lt;/ol&gt;
&lt;p&gt;Here’s how I approached each of these tasks. 
&lt;p&gt;  
&lt;h4&gt;Scraping a photo of the day page&lt;/h4&gt;
&lt;p&gt;The first order of business for scraping a page like this is simply to fetch the page, tidy it into XML so we can navigate it using tools like XPath.  The WSO2 Mashup Server provides a “Scraper” object that accepts an XML language describing the steps involved in scraping.  This configuration language is defined by the &lt;strong&gt;&lt;a href="http://web-harvest.sourceforge.net/index.php"&gt;Web Harvest&lt;/a&gt;&lt;/strong&gt; component that we use for scraping.  I usually start with a scraping mashup using a simple function that configures and performs the scrape, and returns the results:&lt;pre&gt; &lt;br&gt;function scrape_picture_page() {&lt;br&gt;  var config =&lt;br&gt;    &amp;lt;config&amp;gt;&lt;br&gt;      &amp;lt;var-def name='response'&amp;gt;&lt;br&gt;        &amp;lt;html-to-xml&amp;gt;&lt;br&gt;          &amp;lt;http method='get' &lt;br&gt;              url=&amp;quot;http://photography.nationalgeographic.com/photography/ ¬&lt;br&gt;                   photo-of-the-day&amp;quot; /&amp;gt;&lt;br&gt;        &amp;lt;/html-to-xml&amp;gt;&lt;br&gt;      &amp;lt;/var-def&amp;gt;&lt;br&gt;    &amp;lt;/config&amp;gt;;&lt;br&gt; &lt;br&gt;  var scraper = new Scraper(config);&lt;br&gt; &lt;br&gt;  var bodyWithoutXMLDecl = &lt;br&gt;      scraper.response.substring(scraper.response.indexOf('?&amp;gt;') + 2);&lt;br&gt;  var result = new XML(bodyWithoutXMLDecl);&lt;br&gt; &lt;br&gt;  return result;&lt;br&gt;}&lt;/pre&gt;
&lt;p&gt;The config language itself is pretty straightforward, once you learn to read it inside out – the &amp;lt;http&amp;gt; element fetches the requested URL, the &amp;lt;html-to-xml&amp;gt; does just what it sounds like and tidies the result, which is put into a variable named “response”.  The scrape is performed by initializing a new “Scraper” object with the config, and the result is made available through the “response” property on the result – corresponding to the “response” variable we defined within the config file.  One trick though – the result is a stream of XML text, including an XML declaration.  The E4X extensions can parse this into XML (new XML()), but can’t handle the XML declaration.  We have to strip off the declaration ourselves using string manipulation. 
&lt;p&gt;By placing the above function in a file named “nationalgeographic.js” in the “scripts” directory of the Mashup Server, a Web service with a scrape_picture_page operation will be deployed.  We can get to it through the try-it page (&lt;a href="http://localhost:7762/services/jonathan/nationalgeographic?tryit"&gt;http://localhost:7762/services/jonathan/nationalgeographic?tryit&lt;/a&gt;) and see what the tidied HTML looks like for the page. 
&lt;p&gt;Extracting the data from the page can be a tedious process, involving looking at HTTP request-response pairs and trolling through the HTML source of a page.  Fortunately the National Geographic site’s HTML is simple and straightforwardly structured, with a number of well-placed identifiers to help us zero in on the interesting content.  I usually end up using Firebug (Firefox debugging extension) to navigate the live HTML of the page and develop some XPath expressions that extract the desired metadata for the page.  I’ve also found that, since Web Harvest communicates between components using strings rather than parsed XML, that defining a lot of XPath filters to extract information one element at a time during a scrape can perform poorly.  Instead it seems much faster to wrap a series of XPath expressions into a simple XSLT stylesheet so the XML can be parsed once, queried as much as needed, and an XML structure containing the results returned in one action.  To do that, I added an XSLT stylesheet to the above configuration:&lt;pre&gt;  var config =&lt;br&gt;    &amp;lt;config&amp;gt;&lt;br&gt;      &amp;lt;var-def name='response'&amp;gt;&lt;br&gt;        &amp;lt;xslt&amp;gt;&lt;br&gt;          &amp;lt;xml&amp;gt;&lt;br&gt;            &amp;lt;html-to-xml&amp;gt;&lt;br&gt;              &amp;lt;http method='get' url={url} /&amp;gt;&lt;br&gt;            &amp;lt;/html-to-xml&amp;gt;&lt;br&gt;          &amp;lt;/xml&amp;gt;&lt;br&gt;          &amp;lt;stylesheet&amp;gt;&amp;lt;![CDATA[&lt;br&gt;           &amp;lt;xsl:stylesheet version=&amp;quot;1.0&amp;quot;&lt;br&gt;                            xmlns:xsl=&amp;quot;http://www.w3.org/1999/XSL/Transform&amp;quot;&amp;gt;&lt;br&gt;              &amp;lt;xsl:output method=&amp;quot;xml&amp;quot; omit-xml-declaration=&amp;quot;yes&amp;quot;/&amp;gt;&lt;br&gt;              &amp;lt;xsl:template match=&amp;quot;/&amp;quot;&amp;gt;&lt;br&gt;               &amp;lt;photo&amp;gt;&lt;br&gt;                  &amp;lt;xsl:for-each select=&amp;quot;//*[@id='content-center-well']&amp;quot;&amp;gt;&lt;br&gt;                    &amp;lt;date&amp;gt;&amp;lt;xsl:value-of select=&amp;quot;div[@class='date']&amp;quot;/&amp;gt;&amp;lt;/date&amp;gt;&lt;br&gt;                    &amp;lt;previous&amp;gt;http://photography.nationalgeographic.com ¬&lt;br&gt;                      &amp;lt;xsl:value-of &lt;br&gt;                          select=&amp;quot;div[@class='slide-navigation'][1]/p/a/@href&amp;quot;/&amp;gt;&lt;br&gt;                    &amp;lt;/previous&amp;gt;&lt;br&gt;                    &amp;lt;xsl:for-each select=&amp;quot;div[@class='image-viewer clearfix']&amp;quot;&amp;gt;&lt;br&gt;                      &amp;lt;xsl:for-each select=&amp;quot;table/tbody/tr[1]/td/a&amp;quot;&amp;gt;&lt;br&gt;                        &amp;lt;page&amp;gt;http://photography.nationalgeographic.com/photography/¬&lt;br&gt;                          photo-of-the-day/&amp;lt;xsl:value-of&lt;br&gt;                          select=&amp;quot;substring-before(substring-after(@href,'enlarge/'),&lt;br&gt;                          '_pod_image.html')&amp;quot;/&amp;gt;.html&amp;lt;/page&amp;gt;&lt;br&gt;                        &amp;lt;xsl:variable name=&amp;quot;href&amp;quot; &lt;br&gt;                          select=&amp;quot;concat('http://photography.nationalgeographic.com', &lt;br&gt;                                substring-before(img/@src, '-ga.jpg'))&amp;quot;/&amp;gt;&lt;br&gt;                        &amp;lt;location type='small'&amp;gt;&lt;br&gt;                          &amp;lt;xsl:value-of select=&amp;quot;$href&amp;quot;/&amp;gt;-ga.jpg&amp;lt;/location&amp;gt;&lt;br&gt;                        &amp;lt;location type='medium'&amp;gt;&lt;br&gt;                          &amp;lt;xsl:value-of select=&amp;quot;$href&amp;quot;/&amp;gt;-sw.jpg&amp;lt;/location&amp;gt;&lt;br&gt;                        &amp;lt;location type='large'&amp;gt;&lt;br&gt;                          &amp;lt;xsl:value-of select=&amp;quot;$href&amp;quot;/&amp;gt;-lw.jpg&amp;lt;/location&amp;gt;&lt;br&gt;                        &amp;lt;location type='wide'&amp;gt;&lt;br&gt;                          &amp;lt;xsl:value-of select=&amp;quot;$href&amp;quot;/&amp;gt;-xl.jpg&amp;lt;/location&amp;gt;&lt;br&gt;                      &amp;lt;/xsl:for-each&amp;gt;&lt;br&gt;                                               &lt;br&gt;                      &amp;lt;xsl:for-each select=&amp;quot;div[@class='summary']&amp;quot;&amp;gt;&lt;br&gt;                        &amp;lt;title&amp;gt;&amp;lt;xsl:value-of select=&amp;quot;h3&amp;quot;/&amp;gt;&amp;lt;/title&amp;gt;&lt;br&gt;                        &amp;lt;credit&amp;gt;&amp;lt;xsl:value-of select=&amp;quot;p[@class='credit']&amp;quot;/&amp;gt;&amp;lt;/credit&amp;gt;&lt;br&gt;                        &amp;lt;description&amp;gt;&lt;br&gt;                          &amp;lt;xsl:copy-of select=&amp;quot;div[@class='description']/node()&amp;quot;/&amp;gt;&lt;br&gt;                        &amp;lt;/description&amp;gt;&lt;br&gt;                      &amp;lt;/xsl:for-each&amp;gt;&lt;br&gt;                    &amp;lt;/xsl:for-each&amp;gt;&lt;br&gt;                  &amp;lt;/xsl:for-each&amp;gt;&lt;br&gt;                &amp;lt;/photo&amp;gt;&lt;br&gt;            &amp;lt;/xsl:template&amp;gt;&lt;br&gt;            &amp;lt;/xsl:stylesheet&amp;gt;&lt;br&gt;          ]]&amp;gt;&amp;lt;/stylesheet&amp;gt;&lt;br&gt;        &amp;lt;/xslt&amp;gt;&lt;br&gt;      &amp;lt;/var-def&amp;gt;&lt;br&gt;    &amp;lt;/config&amp;gt;;&lt;/pre&gt;
&lt;p&gt;Again, fairly straightforward – the &amp;lt;xslt&amp;gt; task has two inputs, &amp;lt;xml&amp;gt; and &amp;lt;stylesheet&amp;gt;.  The stylesheet unfortunately has to be enclosed in a CDATA section rather than as straight XML.  One other nice trick though – when the output is an XSLT template, the “omit-xml-declaration” flag can be used to strip off the XML declaration so we don’t have to do it through text manipulation, simplifying and accelerating our Javascript code. 
&lt;p&gt;So we’re almost there with this capability.  Some minor improvements and adding caching are all we need: 
&lt;ol&gt;
&lt;li&gt;Add an optional  “url” parameter to allow this page to work on any photo-of-the-day page URL.  Using E4X’s curly braces we can substitute this value right into the config file. 
&lt;li&gt;If the result was successful (e.g. the &amp;lt;photo/&amp;gt; element has children), calculate the date in yyyy-mm-dd format and use the storexml service to cache it – choosing a path unlikely to conflict with other users of the storexml service.  To make the storexml service easy to call, we import it’s stub, which I got from &lt;a href="http://localhost:7762/services/system/storexml?stub&amp;amp;lang=e4x&amp;amp;localhost=true"&gt;http://localhost:7762/services/system/storexml?stub&amp;amp;lang=e4x&amp;amp;localhost=true&lt;/a&gt; and saved into the nationalgeographic.resources folder which serves as the sandbox for this service.  It’s important to save a copy because when the Mashup Server boots up the nationalgeographic service might be deployed before the storexml service – attempts to generate the stub at that time will fail and cause the nationalgeographic service to fail too.  The Mashup Server doesn’t yet track these dependencies (and we’re still thinking about whether this is a tractable problem or not.) 
&lt;li&gt;Since this operation isn’t really supposed to be called by end-users of the feed, I could make it private using scrape_picture_page.visible = “false”, but instead I’ve just used the “operationName” property to rename it, indicating to users that it really is just for test purposes. 
&lt;li&gt;Add type annotations. 
&lt;li&gt;Add documentation annotations (not shown below.) &lt;/ol&gt;&lt;pre&gt;system.include(&amp;quot;storexml.stub.js&amp;quot;);&lt;br&gt;var cachePath = &amp;quot;nationalgeographic/cache/&amp;quot;;&lt;br&gt; &lt;br&gt;scrape_picture_page.operationName = &amp;quot;test_scrape_picture_page&amp;quot;;&lt;br&gt;scrape_picture_page.inputTypes = {&amp;quot;url&amp;quot; : &amp;quot;xs:string?&amp;quot;};&lt;br&gt;scrape_picture_page.outputType = &amp;quot;xml&amp;quot;;&lt;br&gt;function scrape_picture_page(url) {&lt;br&gt;  if (url == null)&lt;br&gt;    url = &amp;quot;http://photography.nationalgeographic.com/photography/photo-of-the-day&amp;quot;;&lt;br&gt;  var config =&lt;br&gt;    &amp;lt;config&amp;gt;&lt;br&gt;      &amp;lt;var-def name='response'&amp;gt;&lt;br&gt;        &amp;lt;xslt&amp;gt;&lt;br&gt;          &amp;lt;xml&amp;gt;&lt;br&gt;            &amp;lt;html-to-xml&amp;gt;&lt;br&gt;            &amp;lt;http method='get' url={url} /&amp;gt;&lt;br&gt;            &amp;lt;/html-to-xml&amp;gt;&lt;br&gt;          &amp;lt;/xml&amp;gt;&lt;br&gt;         &amp;lt;stylesheet&amp;gt;&lt;br&gt;            ...&lt;br&gt;          &amp;lt;/stylesheet&amp;gt;&lt;br&gt;        &amp;lt;/xslt&amp;gt;&lt;br&gt;      &amp;lt;/var-def&amp;gt;&lt;br&gt;    &amp;lt;/config&amp;gt;;&lt;br&gt; &lt;br&gt;  var scraper = new Scraper(config);&lt;br&gt; &lt;br&gt;  var result = new XML(scraper.response);&lt;br&gt;   &lt;br&gt;  if (result.hasComplexContent()) {&lt;br&gt;    var date = xsDate(new Date(result.date));&lt;br&gt;    storexml.store(cachePath + date, result);&lt;br&gt;  }&lt;br&gt; &lt;br&gt;  return result;&lt;br&gt;}&lt;/pre&gt;&lt;pre&gt;xsDate.visible = false;&lt;br&gt;function xsDate(d)&lt;br&gt;{&lt;br&gt;  return d.getUTCFullYear() + &amp;quot;-&amp;quot; +&lt;br&gt;       (d.getUTCMonth() &amp;lt; 9 ? &amp;quot;0&amp;quot;: &amp;quot;&amp;quot; ) + (d.getUTCMonth() + 1) + &amp;quot;-&amp;quot; +&lt;br&gt;         (d.getUTCDate() &amp;lt; 10 ? &amp;quot;0&amp;quot;: &amp;quot;&amp;quot; ) + d.getUTCDate();&lt;br&gt;}&lt;/pre&gt;
&lt;p&gt;As an aside, this shows a couple of my wishes: 
&lt;ol&gt;
&lt;li&gt;&amp;lt;xml&amp;gt; is a reserved tag name in XML, it’s unfortunate that Web Harvest doesn’t use something else. 
&lt;li&gt;Web Harvest’s requirement that the stylesheet be enclosed in a CDATA section is unfortunate – it means well-formedness errors can’t be caught at Javascript/E4X compile time, but at runtime.  This slows down the development process.  I could put the stylesheet in a separate file, but that just makes it harder to share the service and see what’s going on. 
&lt;li&gt;I’d prefer a way to get E4X XML back from Web Harvest directly so I wouldn’t have to parse it myself, worry about the XML Declaration, and so forth.  Maybe we can do something about this in a future release. 
&lt;li&gt;Managing date formats becomes a bit of a chore.  I prefer the operations and cache to work on xs:date format (yyyy-mm-dd), but the page metadata is in the form “Month day, year” (directly from the scraped page).  And Javascript prefers to manipulate dates in its own Date object.  Soon we’ll see that the RSS profile defines a subset of the Javascript serialization that means a fourth conversion. &lt;/ol&gt;
&lt;h4&gt;Finding a picture for a particular date&lt;/h4&gt;
&lt;p&gt;Now that we have a function that can scrape a page given a URL, and given that the data returned and cached by that function contains a link to the page for the previous day’s page, we can do some walking around in the cache to find data for a particular date.  That’s what this function does. 
&lt;p&gt;First, we look in the cache for a photo’s metadata.  If it’s there, we can simply return it – we’re done.  Otherwise we need to find the URL for the page representing that date and call the scrape_picture_page operation. 
&lt;p&gt;If I can’t find the requested date in the cache, I look for the next earlier date, and so on, until I do find a photo in the cache (or I reach today’s date).  That’s the first while loop.  Then, using the &amp;lt;previous&amp;gt; page url, I work backward again, incidentally populating the cache as I go, until I’m back to the date I was looking for.  The couple of “if” statements look for exceptional conditions: the first one handles the case where I’ve looked all the way forward till today but still haven’t found anything in the cache, and the second makes sure that if a page can’t be scraped for some reason that we give up and return what little we have before we dig ourselves any deeper.&lt;pre&gt;picture_for_date.inputTypes = {&amp;quot;date&amp;quot; : &amp;quot;xs:string&amp;quot;};&lt;br&gt;picture_for_date.outputType = &amp;quot;xml&amp;quot;;&lt;br&gt;function picture_for_date(date) {&lt;br&gt;  try {&lt;br&gt;    return storexml.retrieve(cachePath + date);&lt;br&gt;  } catch (e) {&lt;br&gt;    print(&amp;quot;failed to find cached photo for date &amp;quot; + date);&lt;br&gt;    var photo;&lt;br&gt;    var startDate = parseDate(date);&lt;br&gt;    var today = new Date();&lt;br&gt;    // work forwards in the cache until we find something (or hit today)&lt;br&gt;    while (startDate &amp;lt;= today) {&lt;br&gt;      try {&lt;br&gt;        photo = storexml.retrieve(cachePath + xsDate(startDate));&lt;br&gt;        break;&lt;br&gt;      } catch (e) {&lt;br&gt;        startDate.setUTCDate(startDate.getUTCDate() + 1);&lt;br&gt;      }&lt;br&gt;    }&lt;br&gt;    // start with the most current thing in the cache (if any) an work &lt;br&gt;    // backwards to the requested date, filling in the cache as we go...&lt;br&gt;    var targetDate = parseDate(date);&lt;br&gt;    while (startDate &amp;gt; targetDate) {&lt;br&gt;      var previousPageUrl;&lt;br&gt;        if (photo == null) previousPageUrl = null;&lt;br&gt;        else previousPageUrl = photo.previous;&lt;br&gt;       &lt;br&gt;        print(&amp;quot;fetching photo for &amp;quot; + startDate);&lt;br&gt;        photo = scrape_picture_page(previousPageUrl);&lt;br&gt;        if (!photo.hasComplexContent())&lt;br&gt;          break;&lt;br&gt;        startDate.setUTCDate(startDate.getUTCDate() - 1);&lt;br&gt;    }&lt;br&gt;       &lt;br&gt;    return photo;&lt;br&gt;  }&lt;br&gt;}&lt;/pre&gt;
&lt;h4&gt;Generating the feed&lt;/h4&gt;
&lt;p&gt;Now we have all the pieces in place to aggregate the data and generate a list of some kind as output.  The picture_of_the_day operation does that for us. 
&lt;p&gt;The function has some parameters controlling aspects of the feed – whether to link to the small, medium, large, or wide aspect ratio images, and how many items to include.  If no number is specified, we generate a feed of the latest 30 photos – just long enough to enjoy the photo but not so long we get tired of it. 
&lt;p&gt;The WSO2 Mashup Server has a Feed object to help construct feeds, but because I’m targeting this feed at the Google Photos Screensaver I need to include some feed extensions that aren’t supported in the 0.2 release (though they’ve just been added to the nightly build!).  It’s not hard to create an RSS by hand though, so that’s what I chose to do.  First I prepopulate the channel with title, links, and description, and then loop through the photos adding an item for each of them.  The first time through the loop, I also add in a &amp;lt;pubDate&amp;gt; reflecting the date of today’s photo. 
&lt;p&gt;Again, this isn’t rocket science – the hardest thing is simply to format the dates appropriately.  During the loop I use Javascript Date objects to increment days and tick over at the end of the month.  I convert that to an xs:date to access the cache, to an RSS Profile-conformant string for the &amp;lt;pubDate&amp;gt;, and to an xs:dateTime for use in the &amp;lt;atom:published/&amp;gt; element, which seems useful for the subscription page displayed in Internet Explorer 7.&lt;pre&gt;picture_of_the_day.inputTypes = &lt;br&gt;     {&amp;quot;size&amp;quot; : &amp;quot;small | medium | large | wide&amp;quot;, &amp;quot;numPhotos&amp;quot; : &amp;quot;number?&amp;quot;};&lt;br&gt;picture_of_the_day.outputType = &amp;quot;#raw&amp;quot;;&lt;br&gt;function picture_of_the_day(size, numPhotos) {&lt;br&gt;  if (numPhotos == null) numPhotos = 30;&lt;br&gt; &lt;br&gt;  var feed =&lt;br&gt;    &amp;lt;rss version=&amp;quot;2.0&amp;quot;&amp;gt;&lt;br&gt;      &amp;lt;channel&amp;gt;&lt;br&gt;        &amp;lt;title&amp;gt;National Geographic Picture-of-the-day (from WSO2 Mashup Server)&amp;lt;/title&amp;gt;&lt;br&gt;        &amp;lt;link&amp;gt;http://mashups.wso2.org/services/nationalgeographic/¬&lt;br&gt;              picture_of_the_day?size={size}&amp;lt;/link&amp;gt;&lt;br&gt;        &amp;lt;description&amp;gt;WSO2 Mashup Server mashup acquiring and caching links to the ¬&lt;br&gt;          National Geographic Picture of the Day &lt;br&gt;          (http://photography.nationalgeographic.com/photography/picture-of-the-day),&lt;br&gt;          and exposing them as a feed.  Sizes of &amp;quot;small&amp;quot;, &amp;quot;medium&amp;quot;, &amp;quot;large&amp;quot;, and &amp;quot;wide&amp;quot;&lt;br&gt;          are available. A max number of photos can be specified with the &amp;quot;numPhotos&amp;quot; &lt;br&gt;          parameter.&amp;lt;/description&amp;gt;&lt;br&gt;      &amp;lt;/channel&amp;gt;&lt;br&gt;    &amp;lt;/rss&amp;gt;;&lt;br&gt; &lt;br&gt;  var startDate = new Date();&lt;br&gt;  var photo, photoDate, url, urlsmall, entry;&lt;br&gt;  for (var i = 0; i &amp;lt; numPhotos; i++) {&lt;br&gt;    photo = picture_for_date(xsDate(startDate));&lt;br&gt;    if (photo.hasComplexContent()) {&lt;br&gt;      url = photo.location.(@type == size).toString();&lt;br&gt;      urlsmall = photo.location.(@type == 'small').toString();&lt;br&gt;      photoDate = new Date(photo.date.toString());&lt;br&gt;      if (i == 0) {&lt;br&gt;        feed.channel.appendChild(&amp;lt;pubDate&amp;gt;{rssDate(photoDate)}&amp;lt;/pubDate&amp;gt;);&lt;br&gt;      }&lt;br&gt;      entry = &amp;lt;item xmlns:media=&amp;quot;http://search.yahoo.com/mrss/&amp;quot;&amp;gt;&lt;br&gt;          {photo.title}&lt;br&gt;                &amp;lt;description&amp;gt;&lt;br&gt;                  &amp;amp;lt;a href='{url}'&amp;gt;&amp;amp;lt;img src='{urlsmall}'/&amp;gt;&amp;amp;lt;/a&amp;gt;&lt;br&gt;                  {photo.description.*.toXMLString()}&lt;br&gt;                &amp;lt;/description&amp;gt;&lt;br&gt;                &amp;lt;pubDate&amp;gt;{rssDate(photoDate)}&amp;lt;/pubDate&amp;gt;&lt;br&gt;                &amp;lt;link&amp;gt;{photo.page.toString()}&amp;lt;/link&amp;gt;&lt;br&gt;                &amp;lt;guid isPermaLink='false'&amp;gt;{photo.page.toString()}&amp;lt;/guid&amp;gt;&lt;br&gt;                &amp;lt;media:content url={url} type=&amp;quot;image/jpeg&amp;quot; /&amp;gt;&lt;br&gt;                &amp;lt;media:thumbnail url={urlsmall} /&amp;gt;&lt;br&gt;                &amp;lt;atom:published xmlns:atom=&amp;quot;&lt;a href="http://www.w3.org/2005/Atom"&gt;http://www.w3.org/2005/Atom&lt;/a&gt;&amp;quot;&lt;br&gt;                    &amp;gt;{xsDate(photoDate)}T00:00:00Z&amp;lt;/atom:published&amp;gt;&lt;br&gt;              &amp;lt;/item&amp;gt;;&lt;br&gt;      feed.channel.appendChild(entry);&lt;br&gt;    }&lt;br&gt;    startDate.setUTCDate(startDate.getUTCDate() - 1);&lt;br&gt;  }&lt;br&gt;  return feed;&lt;br&gt;}&lt;/pre&gt;
&lt;p&gt;You can access this operation through the try-it page at &lt;a href="http://localhost:7762/services/jonathan/nationalgeographic?tryit"&gt;http://localhost:7762/services/jonathan/nationalgeographic?tryit&lt;/a&gt; and see that the operation returns a feed.  However, the try-it uses SOAP by default under the covers, which isn’t terribly friendly to feed readers like the Google Photos Screensaver.  No problem – the Mashup Server also exposes it’s operation through a REST interface.  By accessing the URL &lt;a href="http://localhost:7762/services/jonathan/nationalgeographic/photo_of_the_day?size=wide"&gt;http://localhost:7762/services/jonathan/nationalgeographic/photo_of_the_day?size=wide&lt;/a&gt;, you can see the feed directly in the browser, point the screen saver at it, subscribe to it, etc.  By adjusting the “size” and “numPhotos” parameters you can generate variants of the feed that suit your purpose. 
&lt;p&gt;  
&lt;h4&gt;Publishing the feed&lt;/h4&gt;
&lt;p&gt;Once I had the service written, tried it for a day or two to ensure it was stable (and fixed a couple of edge cases as a result), I used the administrative UI in the Mashup Server to publish it to &lt;a href="http://mooshup.com"&gt;http://mooshup.com&lt;/a&gt;, which hosts the service live on the internet for others to use.  The publishing process is simple – click the share button, confirm that &lt;a href="http://mooshup.com/"&gt;http://mooshup.com&lt;/a&gt; is the destination, and click OK.  While we have lots to do to make this site an attractive and useful place for members of the mashup community to hang out, it does give me a stable internet URL for the feed (for example &lt;a href="http://mooshup.com/services/jonathan/nationalgeographic/picture_of_the_day?size=wide"&gt;http://mooshup.com/services/jonathan/nationalgeographic/picture_of_the_day?size=wide&lt;/a&gt;) so others can enjoy it.  You can exercise the try-it page live from there, look at the metadata, or download the service to your local installation of the Mashup Server and run it there. 
&lt;p&gt;  
&lt;h4&gt;Last Word&lt;/h4&gt;
&lt;p&gt;Hopefully this helps you get a feel for the Mashup Server in action.  We did some screen scraping, fairly sophisticated caching by invoking an external storexml Web service, formulated an RSS feed, and made it (and intermediate functions) available through a Web service including SOAP 1.2, SOAP 1.1, and HTTP bindings, including an HTTP GET binding amenable to RSS agents.  Although we didn’t look at them in detail in this article, the Mashup Server generated a try-it page for debugging and exercising the service, WSDL, Schema, stubs for accessing the service simply from Javascript or E4X environments, even generated some human-readable documentation for the mashup.  We ran the service locally, then published it live onto the internet.   It also would not be hard to generate a custom HTML interface providing (for example) a slideshow of these photos, but in this case I wanted to show that user interfaces can go beyond just HTML pages by using Google Photos Screensaver as my ultimate user interface. 
&lt;p&gt;So what’s next for this service?  The main improvement I can think of is rewriting the code to use the Feed object when it becomes capable of handling the images.  It took me a while to figure out which RSS extensions were necessary and it would be nice not to worry about the representation of dates.  Maybe I could even offer an Atom feed in parallel.  Another idea related to performance would be to experiment with a different, perhaps additional, caching strategy – which is to cache the entire feed to disk and periodically refresh it using the recurrence capabilities of the mashup server.  But those are perhaps good topics for future articles! 
&lt;p&gt;Until then, enjoy the great photos available from National Geographic! 
&lt;p&gt;&lt;em&gt;[Updated 6 Feb 2008 - added &amp;quot;jonathan&amp;quot; user to endpoint urls as required by the Mashup Server 1.0 release, and changed the online links to point to &lt;a href="http://mooshup.com"&gt;http://mooshup.com&lt;/a&gt;.]&lt;/em&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=1123747515435059140&amp;page=RSS%3a+Mashing+up+a+National+Geographic+Photo+of+the+Day+Feed&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=auburnmarshes.spaces.live.com&amp;amp;GT1=auburnmarshes"&gt;</description><comments>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!714.entry#comment</comments><guid isPermaLink="true">http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!714.entry</guid><pubDate>Fri, 26 Oct 2007 16:10:49 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://auburnmarshes.spaces.live.com/blog/cns!F985A6952BC07C4!714/comments/feed.rss</wfw:commentRss><wfw:comment>http://auburnmarshes.spaces.live.com/Blog/cns!F985A6952BC07C4!714.entry#comment</wfw:comment><dcterms:modified>2008-02-06T19:47:37Z</dcterms:modified></item></channel></rss>