<?xml version="1.0" encoding='utf-8'?>
<!-- 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
-->
<?xml-stylesheet type="text/xsl" href="https://rollerweblogger.org/roller-ui/styles/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom">
    <title type="html">Blogging Roller</title>
    <subtitle type="html">Dave Johnson on open web technologies, social software and software development</subtitle>
    <id>https://rollerweblogger.org/roller/feed/entries/atom</id>
        <link rel="self" type="application/atom+xml" href="https://rollerweblogger.org/roller/feed/entries/atom?tags=asf" />
    <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/" />
    <updated>2026-04-28T07:02:22+00:00</updated>
    <generator uri="http://roller.apache.org" version="6.1.5">Apache Roller</generator>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/roller-6-released</id>
        <title type="html">Roller 6 released</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/roller-6-released"/>
        <published>2019-12-31T15:04:17+00:00</published>
        <updated>2019-12-31T15:04:50+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;This latest release of Roller includes a new UI that uses&amp;nbsp;&lt;a href=&quot;https://getbootstrap.com/docs/3.3/&quot; target=&quot;_blank&quot;&gt;Twitter Bootstrap 3&lt;/a&gt; and is based on work I started in 2015 and first committed on December 21, 2015 with this commit:&amp;nbsp;&lt;a href=&quot;https://github.com/snoopdave/rollarcus/commit/2da6c3c2e28419f68244e0c362c15be96013d5f9&quot; target=&quot;_blank&quot;&gt;2da6c3c2e28419f68244e0c362c15be96013d5f9&lt;/a&gt;. You can find the &lt;a href=&quot;https://rollerweblogger.org/project/entry/apache-roller-6-released&quot; target=&quot;_blank&quot;&gt;details on on the Roller project blog&lt;/a&gt;. I got lot of help along the way with testing, fixes, dependency upgrades, Java 11 support and more, so thanks to all that helped make this happen.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/digitalocean-kubernetes</id>
        <title type="html">Powered by Digital Ocean Kubernetes</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/digitalocean-kubernetes"/>
        <published>2019-02-10T22:42:05+00:00</published>
        <updated>2019-02-10T22:43:12+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="digitalocean" scheme="http://roller.apache.org/ns/tags/" />
        <category term="kubernetes" scheme="http://roller.apache.org/ns/tags/" />
        <category term="roller" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">
&lt;p&gt;Just a note to say that I&amp;#39;ve switched this site over to &lt;a href=&quot;https://blog.digitalocean.com/digitalocean-releases-k8s-as-a-service/&quot;&gt;Digital Ocean Kubernetes&lt;/a&gt; service, which is in Limited Availability right now. &lt;/p&gt;


&lt;p&gt;Digital Ocean&amp;#39;s Kubernetes service is just as simple and well designed as the rest of Digital Ocean. I &lt;a href=&quot;https://rollerweblogger.org/roller/entry/powered-by-kubernetes&quot;&gt;mentioned before&lt;/a&gt; that I rolled my own Kubernetes cluster via Ansible and Kubeadm. Now I can delete all those config files and that&amp;#39;s a good thing. Plus, the price is right; I can get by with one $10/month node (1 CPU / 2 GB memory) and a $10/month load balancer.&lt;/p&gt;


&lt;p&gt;&lt;div style=&quot;margin:1em 0 1em 0;text-align:center;width:100%;&quot;&gt;&lt;img src=&quot;https://rollerweblogger.org/roller/mediaresource/a352bcf3-b7d9-4f2d-821d-a3ae42e0b06c&quot; width=&quot;80%&quot; halign=&quot;middle&quot;&gt;&lt;/div&gt;&lt;/p&gt;


&lt;p&gt;To get this site up and running I had to deploy four things to my cluster. I installed the &lt;a href=&quot;https://www.nginx.com/products/nginx/kubernetes-ingress-controller/&quot;&gt;NGINX Ingress Controller&lt;/a&gt;, &lt;a href=&quot;https://cert-manager.readthedocs.io/en/latest/&quot;&gt;Cert-Manager&lt;/a&gt; for automatic creation of Let&amp;#39;s Encrypt TLS certs, &lt;a href=&quot;https://www.postgresql.org&quot;&gt;PostgreSQL&lt;/a&gt; and my custom build of &lt;a href=&quot;https://roller.apache.org&quot;&gt;Apache Roller&lt;/a&gt;. All of that went pretty smoothly and I didn&amp;#39;t run into and problems that I could blame on Digital Ocean. &lt;/p&gt;

</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/roller-6-0-0-snapshot</id>
        <title type="html">Roller 6.0.0-SNAPSHOT</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/roller-6-0-0-snapshot"/>
        <published>2019-01-26T22:13:38+00:00</published>
        <updated>2019-01-26T22:14:25+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="apacheroller" scheme="http://roller.apache.org/ns/tags/" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;Upgraded this site to Roller 6.0.0-SNAPSHOT today, which meant an hour of fiddling around with my private Docker registry, then giving up and using the one free private repository offered by DockerHub and then, another hour of futzing around trying to figure out my PostgreSQL JDBC driver doesn&amp;#39;t work anymore (I inadvertently upgraded from JDK 1.7 to 1.8) and why I can&amp;#39;t seem to upgrade it (Kubernetes caches Docker images unless you set imagePullPolicy to always). In the end, I got it working. This post is written in the yet to be officially release Apache Roller 6.0.0-SNAPSHOT version.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Side note&lt;/b&gt;: the new rich-text editor in Roller is now &lt;a href=&quot;https://summernote.org&quot;&gt;Summernote&lt;/a&gt; and it seems quite nice. I need to tweak it a bit because there is currently no way to set the font or add a link unless you switch to raw HTML mode.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/roller-6-snapshot</id>
        <title type="html">Roller&amp;#39;s new web UI</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/roller-6-snapshot"/>
        <published>2019-01-21T15:59:00+00:00</published>
        <updated>2019-05-27T20:14:12+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="docker" scheme="http://roller.apache.org/ns/tags/" />
        <category term="postgresql" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tomcat" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;About three years ago I decided to modernize and improve the &lt;a href=&quot;http://roller.apache.org&quot;&gt;Apache Roller&lt;/a&gt; web UI by rewriting the JSP pages to use the &lt;a href=&quot;https://github.com/struts-community-plugins/struts2-bootstrap&quot;&gt;Struts 2 Bootstrap&lt;/a&gt; tags, which use Twitter&amp;#39;s &lt;a href=&quot;https://getbootstrap.com/docs/3.3/components/&quot;&gt;Bootstrap v3&lt;/a&gt; components and JavaScipt. I also wanted to replace all the HTML &lt;code&gt;table&lt;/code&gt;-based formatting with &lt;code&gt;div&lt;/code&gt;&amp;#39;s and Bootstrap, do a bunch of other improvements and make Roller&amp;#39;s web UI less clunky and annoying.&lt;/p&gt;

&lt;p&gt;Converting Roller&amp;#39;s eight-five JSP pages was a big task and I did not have much time for it. That&amp;#39;s why it took three years. Ironically, the Roller modernization project leaves Roller three years out of date. Still, I think it is a huge improvement over the Roller v5 web UI and I want to get it released in Roller v6. Currently, this work is available as &lt;a href=&quot;https://github.com/apache/roller/pull/22&quot;&gt;Pull Request #22&lt;/a&gt; and you can find some screenshots there too. Here&amp;#39;s one:&lt;/p&gt;

&lt;img src=&quot;https://rollerweblogger.org/roller/mediaresource/23986d06-37aa-48c1-8301-90419520953b&quot; alt=&quot;screenshot of Roller Edit Entry page&quot; style=&quot;max-width:30em;padding:1em;border:1px;&quot;&gt;

&lt;h4&gt;Try it with Docker-Compose&lt;/h4&gt;

&lt;p&gt;I also did some work to make it super-easy to try the Roller v6 snapshot pre-release for yourself, by using &lt;a href=&quot;https://docs.docker.com/compose/&quot;&gt;Docker Compose&lt;/a&gt;. You don&amp;#39;t have to fiddle with Tomcat or PostgreSQL. You can find a simple Dockerfile for running Roller v2 snapshot and a &lt;b&gt;docker-compose.yml&lt;/b&gt; file linked below. And you can find a Docker image in my &lt;a href=&quot;https://cloud.docker.com/u/snoopdave/repository/docker/snoopdave/roller&quot;&gt;DockerHub repo&lt;/a&gt;.&lt;/p&gt;

If you want to try Roller v6 snapshot, here&amp;#39;s what you need to do:

&lt;div style=&quot;margin-left:2em;&quot;&gt;
&lt;p&gt;&lt;b&gt;1&lt;/b&gt; - If you don&amp;#39;t aleady have it, install Docker&lt;/p&gt;

&lt;p&gt;&lt;b&gt;2&lt;/b&gt; - Create a directory on your computer where you want Roller to store it&amp;#39;s data.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;3&lt;/b&gt; - Save this file &lt;a href=&quot;https://github.com/apache/roller/blob/0e77733a4567ad19926ea81b6d7afb0de376b908/deployment/docker-compose/docker-compose.yml&quot;&gt;&lt;b&gt;docker-compose.yml&lt;/b&gt;&lt;/a&gt; to that new directory.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;4&lt;/b&gt; - Open a shell in that new directory and run:&lt;/p&gt;

       &lt;p&gt;&lt;pre&gt;docker-compose up&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;5&lt;/b&gt; - Watch the PostgreSQL and Roller startup logs scroll by&lt;/p&gt;

&lt;p&gt;&lt;b&gt;6&lt;/b&gt; - When the log scroll slows go to http://localhost:8080 to access Roller and go through the initial setup.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Alternatively, if you want to try Roller the hard way, you can get the regular-style v6 SNAPSHOT release files here &lt;a href=&quot;https://dist.apache.org/repos/dist/dev/roller/roller-6.0/v6.0.0/&quot;&gt;roller/roller-6.0/v6.0.0&lt;/a&gt;.&lt;p&gt;

&lt;h4&gt;Let us know how it goes&lt;/h4&gt;

&lt;p&gt;I hope you&amp;#39;ll give Roller v6 snapshot a try and let the project know how it can be improved for your use.  Send feedback to the Roller &lt;a href=&quot;https://cwiki.apache.org/confluence/display/ROLLER/Roller+Mailing+Lists&quot;&gt;mailing lists&lt;/a&gt; or ttweet at us at &lt;a href=&quot;https://twitter.com/apache_roller&quot;&gt;@apache_roller&lt;/a&gt;.&lt;/p&gt;

&lt;br&gt;&lt;/p&gt;&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/powered-by-kubernetes</id>
        <title type="html">Powered by Kubernetes</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/powered-by-kubernetes"/>
        <published>2018-03-13T14:29:55+00:00</published>
        <updated>2018-03-14T21:38:53+00:00</updated> 
        <category term="Web Development" label="Web Development" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="docker" scheme="http://roller.apache.org/ns/tags/" />
        <category term="kubernetes" scheme="http://roller.apache.org/ns/tags/" />
        <category term="postgres" scheme="http://roller.apache.org/ns/tags/" />
        <category term="roller" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">
&lt;p&gt;&lt;img src=&quot;https://rollerweblogger.org/roller/mediaresource/0a80ebe2-257d-48f3-84ba-9aff47c8c3c8&quot; alt=&quot;kubernetes logo&quot; align=&quot;right&quot;&gt; Just a quick note to say that I ditched Docker Swarm and now this rarely updated blog is powered by &lt;a href=&quot;https://kubernetes.io&quot;&gt;Kubernetes&lt;/a&gt;. Total overkill, I know. Like Roller itself, I did it as a learning exercise. I hope to blog more about what I learned by doing this. For now, here&amp;#39;s a quick summary of what I&amp;#39;ve done so far.&lt;/p&gt;


&lt;p&gt;&lt;b&gt;Created a cluster&lt;/b&gt;&lt;/p&gt;


&lt;p&gt;I created a 2-node Kubernetes cluster on &lt;a href=&quot;https://www.digitalocean.com&quot;&gt;Digital Ocean&lt;/a&gt; using some hand-crafted &lt;a href=&quot;https://www.ansible.com&quot;&gt;Ansible&lt;/a&gt; scripts that call &lt;code&gt;apt-get&lt;/code&gt; to install and &lt;code&gt;kubeadm&lt;/code&gt; to start Kubernetes.  I considered using &lt;a href=&quot;https://www.digitalocean.com/community/projects/kubernetes-on-digital-ocean-typhoon&quot;&gt;Typhoon&lt;/a&gt; to create the cluster, but I really wanted to learn how to install Kubernetes &amp;quot;from scratch&amp;quot;.&lt;/p&gt;


&lt;p&gt;&lt;b&gt;Ran two Ingress Controllers&lt;/b&gt;&lt;/p&gt;


&lt;p&gt;To avoid using Digital Ocean&amp;#39;s &lt;a href=&quot;https://www.digitalocean.com/products/load-balancer/&quot;&gt;$20/month load balancer&lt;/a&gt; I&amp;#39;m running an Nginx Ingress controller on each node, and pinning containers to nodes using labels and nodeSelectors. I had to borrow &lt;a href=&quot;https://github.com/poseidon/typhoon/tree/master/addons/nginx-ingress/digital-ocean&quot;&gt;Nginx Controller setup files from the Typhoon project&lt;/a&gt; because I&amp;#39;m still kind of bewildered by Ingresses.&lt;/p&gt;


&lt;p&gt;&lt;b&gt;Deployed my containers&lt;/b&gt;&lt;/p&gt;


&lt;p&gt;Next, I wrote Kubernetes YAML files for deploying my containers: a private Docker Registry, PostgreSQL and my custom Roller image.  Getting the private registry working properly was the biggest challenge. I need private because I don&amp;#39;t want to make my custom Roller image public. Next, I&amp;#39;ll install Jenkins next for CI/CD of my custom Roller build via the &lt;a href=&quot;https://github.com/jenkinsci/kubernetes-plugin&quot;&gt;Jenkins Kubernetes plugin&lt;/a&gt;. &lt;/p&gt;


&lt;p&gt;Let me know if there are any aspects of this that you&amp;#39;d like to see covered in a blog entry, or suggestions for running the cluster without two Ingress Controllers. I&amp;#39;ve already got a post cooking about installing a TLS secured Docker Registry on Kubernetes.&lt;/p&gt;

</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/powered-by-postgresql</id>
        <title type="html">Powered by Postgresql and Docker Swarm</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/powered-by-postgresql"/>
        <published>2017-11-07T21:52:40+00:00</published>
        <updated>2017-11-07T21:58:47+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="docker" scheme="http://roller.apache.org/ns/tags/" />
        <category term="postgresql" scheme="http://roller.apache.org/ns/tags/" />
        <category term="swarm" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">It was somewhat painful but due to some problems with MySQL and Docker, and some general uneasiness with MySQL, I switched this site from MySQL v5.7 to &lt;a href=&quot;https://www.postgresql.org&quot;&gt;PostgreSQL&lt;/a&gt; v10. I also switched over to &lt;a href=&quot;https://docs.docker.com/engine/swarm/&quot;&gt;Docker Swarm&lt;/a&gt;. Here&amp;#39;s the Docker-Compose file that I&amp;#39;m using now to run this site:

&lt;pre&gt;
version: &amp;#39;3.2&amp;#39;

services:

   postgresql:
      image: &amp;quot;postgres:10.0&amp;quot;
      ports:
         - &amp;quot;5432:5432&amp;quot;
      deploy:
         resources:
           limits:
              memory: 50M
      volumes:
         - type: bind
           source: /var/lib/postgresql/data
           target: /var/lib/postgresql/data
      environment:
        - POSTGRES_USER=roller
        - POSTGRES_DB=rollerdb
        - POSTGRES_PASSWORD_FILE=/run/secrets/pg_passwd
      secrets:
        - source: db_passwd
          target: pg_passwd

   roller:
      image: &amp;quot;rwo:latest&amp;quot;
      ports:
        -  &amp;quot;80:8080&amp;quot;
      depends_on:
        - postgresql
      deploy:
         resources:
           limits:
              memory: 800M
      volumes:
        - type: bind
          source: /var/lib/roller
          target: /var/lib/roller
      environment:
        - DB_HOST=postgresql
        - STORAGE_ROOT=/var/lib/roller
        - JAVA_OPTS=&amp;quot;-Xmx700m&amp;quot;

secrets:
  db_passwd:
    file: ./db_passwd.txt
&lt;/pre&gt;

It was a pain, but sometimes pain = gain and I learned a lot. I&amp;#39;m hoping the site will be a bit more stable now. </content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/modernizing-the-roller-ui</id>
        <title type="html">Modernizing the Roller UI</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/modernizing-the-roller-ui"/>
        <published>2016-06-11T18:28:36+00:00</published>
        <updated>2018-02-16T12:42:32+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="bootstrap" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">
&lt;p&gt;&lt;a href=&quot;http://getbootstrap.com&quot;&gt;&lt;/a&gt; I don&amp;#39;t blog very often but I still find time to work on my blog&amp;#39;s software: &lt;a href=&quot;http://roller.apache.org&quot;&gt;Apache Roller&lt;/a&gt;. &lt;/p&gt;


&lt;p&gt;Recently, I decided to focus on improving Roller&amp;#39;s ancient Struts 2-based user interface (UI). I had considered adding a comprehensive API to Roller and building a new UI based on that API, but wow that is a huge amount of work. Instead, I decided to modernize the Roller UI by using Twitter&amp;#39;s &lt;a href=&quot;http://getbootstrap.com&quot;&gt;Bootstrap&lt;/a&gt; components and CSS styles.&lt;/p&gt;


&lt;p&gt;So far, I&amp;#39;ve devoted a couple of weekends to this work and made some pretty good progress. I&amp;#39;m about half-way done. I&amp;#39;m using the &lt;a href=&quot;https://cwiki.apache.org/confluence/display/S2PLUGINS/Bootstrap+Plugin&quot;&gt;Struts2-Bootstrap&lt;/a&gt; plugin, adding better client-side form validation with JavaScript and doing my best to improve the overall user experience. You can see an album of the pages I&amp;#39;ve done so far on Flickr: &lt;a href=&quot;https://www.flickr.com/photos/snoopdave/albums/72157666773620323&quot;&gt;&lt;br&gt;
Roller UI with Bootstrap&lt;/a&gt;. &lt;/p&gt;


&lt;p&gt;I would love any contributions, so if you are interested in helping out, please submit Pull Requests against the &lt;a href=&quot;https://github.com/apache/roller/tree/bootstrap-ui&quot;&gt;bootstrap-ui&lt;/a&gt; branch in the Apache Roller repo on GitHub.&lt;/p&gt;

</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/mandelbrot-viewer-typescript-canvas</id>
        <title type="html">Fractal fun with HTML5 and TypeScript</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/mandelbrot-viewer-typescript-canvas"/>
        <published>2016-01-11T10:00:00+00:00</published>
        <updated>2018-02-16T12:42:44+00:00</updated> 
        <category term="Web Development" label="Web Development" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="canvas" scheme="http://roller.apache.org/ns/tags/" />
        <category term="html5" scheme="http://roller.apache.org/ns/tags/" />
        <category term="typescript" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;
&lt;a href=&quot;https://github.com/snoopdave/mbcanvas&quot;&gt;MbCanvas&lt;/a&gt; is a fun project that I did in 2015: a simple 
&lt;a href=&quot;https://en.wikipedia.org/wiki/Mandelbrot_set&quot;&gt;Mandelbrot Set&lt;/a&gt; viewer written in 
&lt;a href=&quot;http://www.typescriptlang.org/Tutorial&quot;&gt;Typescript&lt;/a&gt; and using the 
&lt;a href=&quot;http://www.w3.org/TR/2dcontext/&quot;&gt;HTML5 Canvas&lt;/a&gt;.  

I did the project to learn more about Typescript and the HTML5 Canvas and I must say, Typescript very nice -- so much easier to read and write than plain old JavaScript, at least for me.&lt;/p&gt;

&lt;p&gt;Here&amp;#39;s an example image from the viewer.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://rollerweblogger.org/roller/mediaresource/d82c09d5-2037-42aa-9b73-6927a754fa36&quot; alt=&quot;mandelbrot set image&quot;&gt;&lt;/p&gt;

&lt;p&gt;The project is fairly easy to build if you&amp;#39;ve got Node and NPM installed, or you can play around with it here: &lt;a href=&quot;http://rollerweblogger.org/mbcanvas&quot;&gt;mbcanvas - Mandelbrot viewer in TypeScript&lt;/a&gt;&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/usergrid-vagrant-updated-for-usergrid</id>
        <title type="html">Usergrid-Vagrant updated for Usergrid 2</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/usergrid-vagrant-updated-for-usergrid"/>
        <published>2016-01-02T11:44:45+00:00</published>
        <updated>2016-05-31T10:51:51+00:00</updated> 
        <category term="Open Source" label="Open Source" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="baas" scheme="http://roller.apache.org/ns/tags/" />
        <category term="usergrid" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;img align=&quot;right&quot; alt=&quot;GitHub logo&quot; src=&quot;https://rollerweblogger.org/roller/mediaresource/153bf8c1-cdef-4510-ab43-605c1fa0c3e9&quot;&gt;

&lt;p&gt;If you&amp;#39;re interested in trying the not-yet-released &lt;a href=&quot;http://usergrid.apache.org&quot;&gt;Apache Usergrid&lt;/a&gt; 2 you might want to checkout my &lt;a href=&quot;https://github.com/snoopdave/usergrid-vagrant&quot;&gt;Usergrid-Vagrant project on GitHub&lt;/a&gt;.  I just updated the project to support Usergrid 2, using the latest code from the Usergrid &amp;quot;release&amp;quot; brach.  The big changes were switching to OpenJDK 8 and adding ElasticSearch.  I also rewrote the scripts to use plain old Bash instead of Groovy.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://github.com/snoopdave/usergrid-vagrant&quot;&gt;https://github.com/snoopdave/usergrid-vagrant&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want the old Usergrid 1 Vagrant-file then checkout the &amp;quot;1.x&amp;quot; branch.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/shiro-not-spring</id>
        <title type="html">Apache Shiro for authentication in Roller</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/shiro-not-spring"/>
        <published>2015-02-09T07:27:50+00:00</published>
        <updated>2018-02-16T12:43:20+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="opensource" scheme="http://roller.apache.org/ns/tags/" />
        <category term="shiro" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;img src=&quot;https://rollerweblogger.org/roller/mediaresource/80d2d56d-a8cd-43f2-825d-d0474b67139b&quot; alt=&quot;Shiro logo&quot; align=&quot;right&quot;&gt;


&lt;p&gt;
This is the third of my 2014 side projects that I&amp;#39;m sharing and one that involves the 
&lt;a href=&quot;http://roller.apache.org&quot;&gt;Apache Roller&lt;/a&gt; blog server and the 
&lt;a href=&quot;http://shiro.apache.org&quot;&gt;Apache Shiro&lt;/a&gt; security framework. 

You might find this interesting if you&amp;#39;re considering using Shiro for authentication and authorization, or if your interested in how security works in Apache Roller.
&lt;/p&gt;


&lt;p&gt;
Inspired by my work with &lt;a href=&quot;http://emberjs.com&quot;&gt;Ember.js&lt;/a&gt; in Fall 2014, I started thinking about what it would take to build an Ember.js-based editor/admin interface for Apache Roller.

To do that, I&amp;#39;d need to add a comprehensive REST API to Roller, and I&amp;#39;d need a way to implement secrity for the new API.

I&amp;#39;ve enjoyed working with &lt;a href=&quot;http://shiro.apache.org&quot;&gt;Apache Shiro&lt;/a&gt;, so I decided that a good first step would be to figure out how to use Apache Shiro in Roller for Roller&amp;#39;s existing web interface.
&lt;/p&gt;

&lt;p&gt;
Working over the winter break I was able to replace Roller&amp;#39;s existing Spring security implementation with Shiro and remove all Spring dependencies from my &lt;a href=&quot;https://github.com/snoopdave/rollarcus&quot;&gt;Rollarcus&lt;/a&gt; fork of Roller. 

Below I&amp;#39;ll describe what I had to do get Shiro working for Form-base Authentication in Roller.
&lt;/p&gt;

&lt;h3&gt;Creating a Shiro Authorizing Realm&lt;/h3&gt;

&lt;p&gt;The first step in hooking Shiro into Roller is to implement a Shiro interface called &lt;code&gt;ShiroAuthorizingRealm&lt;/code&gt;. 

This interface enables Shiro to do username and password checks for users when they attempt to login, and to get the user&amp;#39;s roles. 
&lt;/p&gt;

&lt;p&gt;
Below is the first part of the class, which includes the &lt;code&gt;doGetAuthenticationInfo()&lt;/code&gt; method, which returns the &lt;code&gt;AuthenticationInfo&lt;/code&gt; for a user specified by an &lt;code&gt;AuthenticationToken&lt;/code&gt; that includes the user&amp;#39;s username. 

In other words, this method allows Shiro to look-up a user by providing a username and get back the user&amp;#39;s (hashed) password, so that Shiro can validate a user&amp;#39;s username and password.
&lt;/p&gt;

&lt;b&gt;ShiroAuthorizingRealm.java (&lt;a href=&quot;https://github.com/snoopdave/rollarcus/blob/shiro_not_spring/app/src/main/java/org/apache/roller/weblogger/auth/ShiroAuthorizingRealm.java&quot;&gt;link&lt;/a&gt;)&lt;/b&gt;
&lt;pre class=&quot;brush:js&quot;&gt;
public class ShiroAuthorizingRealm extends AuthorizingRealm {

    public ShiroAuthorizingRealm(){
        setName(&amp;quot;ShiroAuthorizingRealm&amp;quot;);
        setCredentialsMatcher(
            new HashedCredentialsMatcher(Sha1Hash.ALGORITHM_NAME));
    }

    @Override
    public AuthenticationInfo doGetAuthenticationInfo(
        AuthenticationToken authToken) throws AuthenticationException {

        UsernamePasswordToken token = (UsernamePasswordToken) authToken;

        User user;
        try {
            user = loadUserByUsername( token.getUsername() );

        } catch (WebloggerException ex) {
            throw new AuthenticationException(
                &amp;quot;Error looking up user &amp;quot; + token.getUsername(), ex);
        }

        if (user != null) {
            return new SimpleAuthenticationInfo( 
                user.getUserName(), user.getPassword(), getName());

        } else {
            throw new AuthenticationException(
                &amp;quot;Username not found: &amp;quot; + token.getUsername());
        }
    }

&lt;/pre&gt;

&lt;p&gt;In the code above you can see how we pull the username out of the &lt;code&gt;authToken&lt;/code&gt; provided by Shiro and we call a method, &lt;code&gt;loadUserByUserName()&lt;/code&gt;, which uses Roller&amp;#39;s Java API to load a Roller user object specified by name.&lt;/p&gt;

&lt;p&gt;The next method of interest is &lt;code&gt;doGetAuthorizationInfo()&lt;/code&gt;, which allows Shiro to look-up a user&amp;#39;s Role. This allows Shiro to detmerine if the user is a Roller admin user or a blog editor.&lt;/p&gt;

&lt;b&gt;ShiroAuthorizingRealm.java (continued)&lt;/b&gt;
&lt;pre class=&quot;brush:js&quot;&gt;

    public AuthorizationInfo doGetAuthorizationInfo(
        PrincipalCollection principals) {

        String userName = (String)
            (principals.fromRealm(getName()).iterator().next());

        User user;
        try {
            user = loadUserByUsername( userName );
        } catch (WebloggerException ex) {
            throw new RuntimeException(&amp;quot;Error looking up user &amp;quot; + userName, ex);
        }

        Weblogger roller = WebloggerFactory.getWeblogger();
        UserManager umgr = roller.getUserManager();

        if (user != null) {
            List roles;
            try {
                roles = umgr.getRoles(user);
            } catch (WebloggerException ex) {
                throw new RuntimeException(
                    &amp;quot;Error looking up roles for user &amp;quot; + userName, ex);
            }
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            for ( String role : roles ) {
                info.addRole( role );
            }
            log.debug(&amp;quot;Returning &amp;quot; + roles.size() 
                + &amp;quot; roles for user &amp;quot; + userName + &amp;quot; roles= &amp;quot; + roles);
            return info;

        } else {
            throw new RuntimeException(&amp;quot;Username not found: &amp;quot; + userName);
        }
    }
&lt;/pre&gt;

&lt;p&gt;In the code above you can see that we use the &lt;code&gt;loadUserByUsername()&lt;/code&gt; too look-up a user by username, then we use Roller&amp;#39;s Java API to get the user&amp;#39;s roles. We add those roles to an instance of the Shiro class &lt;code&gt;SimpleAuthorizationInfo&lt;/code&gt; and return it to Shir.&lt;/p&gt;

&lt;h3&gt;Creating a Shiro Authorizing Filter&lt;/h3&gt;

&lt;p&gt;Now that we&amp;#39;ve implementated a realm, we&amp;#39;ve provided Shiro with everything needed to authenticate Roller users and get access to Roller user role information. Next, we need to configure Shiro to enforce roles for the URL apths found in Roller. Shiro includes a &lt;code&gt;RolesAuthorizationFilter&lt;/code&gt;, which is close to what we need but not exactly right for Roller. I had to extend Shiro&amp;#39;s roles filter so that we can allow a user who has any (not all) of the required roles for a resource.&lt;/p&gt;

&lt;b&gt;RollerRolesAuthorizationFilter.java (&lt;a href=&quot;https://github.com/snoopdave/rollarcus/blob/shiro_not_spring/app/src/main/java/org/apache/roller/weblogger/rest/auth/RollerRolesAuthorizationFilter.java&quot;&gt;link&lt;/a&gt;)&lt;/b&gt;
&lt;pre class=&quot;brush:js&quot;&gt;
public class RollerRolesAuthorizationFilter 
    extends RolesAuthorizationFilter {

    @Override
    public boolean isAccessAllowed( 
        ServletRequest request, 
        ServletResponse response, 
        Object mappedValue) throws IOException {

        final Subject subject = getSubject(request, response);
        final String[] roles = (String[]) mappedValue;

        if (roles == null || roles.length == 0) {
            return true;
        }

        // user is authorized if they have ANY of the roles
        for (String role : roles) {
            if (subject.hasRole(role)) {
                return true;
            }
        }
        return false;
    }
}
&lt;/pre&gt;


&lt;h3&gt;Configuring Shiro for Roller&lt;/h3&gt;

&lt;p&gt;Now that we&amp;#39;ve seen the Java code needed to hook Shiro into Roller, lets look at how we configure Shiro to use that code. We do that using the Shiro configuration file: shiro.ini, as shown below.&lt;/p&gt;

&lt;b&gt;shiro.ini (&lt;a href=&quot;https://github.com/snoopdave/rollarcus/blob/shiro_not_spring/app/src/main/resources/shiro.ini&quot;&gt;link&lt;/a&gt;)&lt;/b&gt;
&lt;pre class=&quot;brush:js&quot;&gt;
[main]

defaultRealm = org.apache.roller.weblogger.auth.ShiroAuthorizingRealm
securityManager.realms = $defaultRealm

cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
securityManager.cacheManager = $cacheManager

authc = org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authc.loginUrl = /roller-ui/login.rol
authc.successUrl = /roller-ui/menu.rol

rollerroles = org.apache.roller.weblogger.rest.auth.RollerRolesAuthorizationFilter

[urls]

/roller-ui/login.rol          = authc
/roller-ui/login-redirect.rol = authc, rollerroles[admin,editor]
/roller-ui/profile**          = authc, rollerroles[admin,editor]
/roller-ui/createWeblog**     = authc, rollerroles[admin,editor]
/roller-ui/menu**             = authc, rollerroles[admin,editor]
/roller-ui/authoring/**       = authc, rollerroles[admin,editor]
/roller-ui/admin/**           = authc, rollerroles[admin]
/rewrite-status/**            = authc, rollerroles[admin]
/roller-services/rest/**      = authcBasic, rollerroles[admin,editor]
&lt;/pre&gt;


&lt;p&gt;
In the configuration file above, you see how we hook in the new &lt;code&gt;ShiroAuthorizingRealm&lt;/code&gt; on line 3.  

The next couple lines are boiler-plate code to hook in Shiro&amp;#39;s caching mechanism and then, on line 9, we configure an authentication method called &lt;code&gt;authc&lt;/code&gt;, which is configured to use Shiro&amp;#39;s Form Authentication feature. 

And, on line 13, we hook in our new &lt;code&gt;RollerRolesAuthorizationFilter&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Next, we tell Shiro that the login page for Roller is &lt;code&gt;/roller-ui/login.rol&lt;/code&gt; and which page to direct a user to on a successful login, &lt;code&gt;/roller-ui/menu.rol&lt;/code&gt;, if the user did not specify which page they wanted to access.

And finally, on lines 17-25, you see the list of Roller URL patterns that need protection, which authentication method to use (authc or authcBasic) and the authorization filter and roles required for access to the URL pattern.
&lt;/p&gt;


&lt;h3&gt;Wrapping up...&lt;/h3&gt;

&lt;p&gt;
That&amp;#39;s all there is to the story of Roller and Shiro so far. 

I was able to get Roller&amp;#39;s form-based authentication working with Shiro, but I did not try to test with OpenID or LDAP, so I assume more work will be necessary to get them working. 

I did the work in my experimental 
&lt;a href=&quot;https://github.com/snoopdave/rollarcus&quot;&gt;Rollarcus&lt;/a&gt; fork of Roller. 

You can get the code from the 
&lt;a href=&quot;https://github.com/snoopdave/rollarcus/tree/shiro_not_spring&quot;&gt;shiro_not_spring&lt;/a&gt; branch. 

Pull requests are quite welcome as are suggestions for improvement. 

Please let me know if you see anything wrong in the above code.
&lt;/p&gt;

&lt;p&gt;
This work may not find its way into Roller proper, but it plays a part in my the next side-project that I will share: A REST API for Roller with JAX-RS. 
&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/usergrid-ember-pt-2</id>
        <title type="html">Usergrid and Ember.js - part 2</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/usergrid-ember-pt-2"/>
        <published>2015-01-26T10:23:01+00:00</published>
        <updated>2018-02-16T12:48:34+00:00</updated> 
        <category term="Web Development" label="Web Development" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="baas" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ember" scheme="http://roller.apache.org/ns/tags/" />
        <category term="javascript" scheme="http://roller.apache.org/ns/tags/" />
        <category term="usergrid" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;In &lt;a href=&quot;http://rollerweblogger.org/roller/entry/usergrid-ember-pt-2&quot;&gt;part one&lt;/a&gt;, I explained the basics of the example Usergrid-Ember &amp;quot;Checkin&amp;quot; app, how the index page is displayed and how login is implemented. In part two, I&amp;#39;ll explain how Ember.js can be hooked into the Usergrid REST API to store and query JSON objects.&lt;/p&gt;

&lt;a href=&quot;http://emberjs.com&quot;&gt;&lt;img src=&quot;https://rollerweblogger.org/roller/mediaresource/87879b47-6b14-4c18-a17e-576a68bf62a0&quot; alt=&quot;Ember logo&quot; align=&quot;right&quot;&gt;&lt;/a&gt;

&lt;p&gt;Ember.js includes a feature referred to as &lt;a href=&quot;http://emberjs.com/guides/models&quot;&gt;Ember-Data&lt;/a&gt;, which provides a persistence interface for storing and retrieving JavaScript objects that could be stored in memory, or stored on a server and accessed via REST API.&lt;/p&gt;

&lt;p&gt;To use Ember-Data with your REST API you&amp;#39;ve got to define an Ember-Data model and add an Ember-Data REST adapter. If your REST API differs from what Ember-Data expects then you will probably have to extend the built-in REST adapter to handle your URL pattens, and extend the built-in REST serializer to handle your JSON format. By extending Ember-Data in this way, you can use it to store and query data from Usergrid without using the Usergrid JavaScript SDK at all. Below I&amp;#39;ll explain what I had to do to make the Checkin app&amp;#39;s Activities collection available via Ember-Data.&lt;/p&gt;


&lt;h3&gt;Define Ember-Data models&lt;/h3&gt;

&lt;p&gt;Ember-Data expects each of your REST API collections to have a defined data model, one that extends the DS.Model class. Here&amp;#39;s what I added for the Activities collection:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;From app.js (&amp;lt;a href=&amp;quot;https://github.com/snoopdave/usergrid-ember/blob/v2/js/app.js#L18&amp;quot;
&amp;gt;link)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;
App.Activity = DS.Model.extend({
  uuid: DS.attr(&amp;#39;string&amp;#39;),
  type: DS.attr(&amp;#39;string&amp;#39;),
  content: DS.attr(&amp;#39;string&amp;#39;),
  location: DS.attr(&amp;#39;string&amp;#39;),
  created: DS.attr(&amp;#39;date&amp;#39;),
  modified: DS.attr(&amp;#39;date&amp;#39;),
  actor: DS.attr(&amp;#39;string&amp;#39;),
  verb: DS.attr(&amp;#39;string&amp;#39;),
  published: DS.attr(&amp;#39;date&amp;#39;),
  metadata: DS.attr(&amp;#39;string&amp;#39;)
});
&lt;/pre&gt;


&lt;h3&gt;Create a custom RESTAdapter&lt;/h3&gt;

&lt;p&gt;The Ember-Data REST adapter expects a REST API to follow some common conventions for URL patterns and for JSON data formats. For example, if your REST API provides a collection of cats then Ember-Data will expect your REST API to work like so:


&lt;p&gt;&lt;b&gt;What Ember-Data expects for a cats collection:&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;GET /cats&lt;/b&gt; - get collection of cats&lt;/li&gt;
&lt;li&gt;&lt;b&gt;POST /cats&lt;/b&gt; - create new cat.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;GET /cats/{cat-id}&lt;/b&gt; - get cat specified by ID.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;PUT /cats/{cat-id}&lt;/b&gt; - update cat specified by ID.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DELETE /cats/{cat-id}&lt;/b&gt; - delete cat specified by ID.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Usergrid follows the above conventions for collections, but there are some exceptions. For example, the Usergrid Activities collection. A GET on the &lt;code&gt;/activities&lt;/code&gt; path will return the Activities of the users that you (i.e. the currently authenticated user) follow. You don&amp;#39;t POST new activities there, instead you post to your own Activities collection at the path &lt;code&gt;/users/{your-user-id}/activities&lt;/code&gt;. It works like this:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Usergrid&amp;#39;s Activities collection:&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;GET /activities&lt;/b&gt; - get Activities of all users that you follow.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;POST /user/{user-id}/activities&lt;/b&gt; - create new Activity for user specified by ID&lt;/li&gt;
&lt;li&gt;&lt;b&gt;GET /user/{user-id}/activities&lt;/b&gt; - get Activities for one specific user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To adapt the Activities collection to Ember-Data, I decided to create a new model called NewActivity. A NewActivity represents the data needed to create a new Activity, here&amp;#39;s the model:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;From app.js (&amp;lt;a href=&amp;quot;https://github.com/snoopdave/usergrid-ember/blob/v2/js/app.js#L132&amp;quot;
&amp;gt;Link)&lt;/b&gt;&lt;/p&gt;&lt;pre class=&quot;brush:js&quot;&gt;
// Must have a special model for new activity because new 
// Activities must be posted to the path /{org}/{app}/users/activities, 
// instead of the path /{org}/{app}/activities as Ember-Data expects.
App.NewActivity = DS.Model.extend({
  content: DS.attr(&amp;#39;string&amp;#39;),
  location: DS.attr(&amp;#39;string&amp;#39;),
  actor: DS.attr(&amp;#39;string&amp;#39;),
  verb: DS.attr(&amp;#39;string&amp;#39;)
});
&lt;/pre&gt;

&lt;p&gt;Then, in Checkin&amp;#39;s custom REST adapter, I added logic to the &lt;code&gt;pathForType()&lt;/code&gt; function to ensure that NewActivities are posted to the correct path. Here&amp;#39;s the adapter:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;From app.js (&amp;lt;a href=&amp;quot;https://github.com/snoopdave/usergrid-ember/blob/v2/js/app.js#L40&amp;quot;
&amp;gt;Link)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;
App.ApplicationAdapter = DS.RESTAdapter.extend({

  host: Usergrid.getAppUrl(),

  headers: function() { 
    if ( localStorage.getItem(&amp;quot;access_token&amp;quot;) ) {
      return { &amp;quot;Authorization&amp;quot;: &amp;quot;Bearer &amp;quot; 
          + localStorage.getItem(&amp;quot;access_token&amp;quot;) }; 
    } 
    return {};
  }.property().volatile(), // ensure value not cached

  pathForType: function(type) {
    var ret = Ember.String.camelize(type);
    ret = Ember.String.pluralize(ret);

    if ( ret == &amp;quot;newActivities&amp;quot; ) {
      // Must have a special logic here for new activity 
      // because new Activities must be posted to the 
      // path /{org}/{app}/users/activities, instead of the 
      // path /{org}/{app}/activities as Ember-Data expects.
      ret = &amp;quot;/users/&amp;quot; + Usergrid.user.username + &amp;quot;/activities&amp;quot;;
    }
    return ret;
  }

});
&lt;/pre&gt;

&lt;p&gt;You can see a couple of other interesting things in the example above. First, there&amp;#39;s the &lt;code&gt;host&lt;/code&gt; field which specifies the base-URL of the REST API for the Checkin app. Next, there&amp;#39;s the &lt;code&gt;headers()&lt;/code&gt; function, which ensures that every request carries the &lt;code&gt;access_token&lt;/code&gt; that was acquired during login.&lt;/p&gt;


&lt;h3&gt;Create a custom RESTSerializer&lt;/h3&gt;

&lt;p&gt;Ember-Data also has expectations about the JSON format returned by a REST API. Unfortunately, what Ember-Data expects and what Usergrid provides are quite different. The two examples below illustrate the differences:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Ember-Data vs. Usergrid JSON formats&lt;/b&gt;&lt;/p&gt;
&lt;table&gt;
   &lt;tr&gt;
      &lt;td valign=&quot;top&quot;&gt;

&lt;p&gt;Ember-Data expects collections like this:&lt;/p&gt;
&lt;pre&gt;
{
   cats: [{
       &amp;quot;id&amp;quot;: &amp;quot;6b2360d0&amp;quot;,
       &amp;quot;name&amp;quot;: &amp;quot;enzo&amp;quot;,
       &amp;quot;color&amp;quot;: &amp;quot;orange&amp;quot;
   },{
       &amp;quot;id&amp;quot;: &amp;quot;a01dfaa0&amp;quot;,
       &amp;quot;name&amp;quot;: &amp;quot;bertha&amp;quot;,
       &amp;quot;color&amp;quot;: &amp;quot;tabby&amp;quot;
   }]
}






&lt;/pre&gt;

      &lt;/td&gt;
      &lt;td&gt;&lt;/td&gt;
      &lt;td valign=&quot;top&quot;&gt;

&lt;p&gt;Usergrid returns collections like this:&lt;/p&gt;
&lt;pre&gt;
{
   action: &amp;quot;get&amp;quot;,
   path: &amp;quot;/cats&amp;quot;,
   count: 2,
   entities: [{
       &amp;quot;uuid&amp;quot;: &amp;quot;6b2360d0&amp;quot;,
       &amp;quot;type&amp;quot;: &amp;quot;cat&amp;quot;,
       &amp;quot;name&amp;quot;: &amp;quot;enzo&amp;quot;,
       &amp;quot;color&amp;quot;: &amp;quot;orange&amp;quot;
   },{
       &amp;quot;uuid&amp;quot;: &amp;quot;a01dfaa1&amp;quot;,
       &amp;quot;type&amp;quot;: &amp;quot;cat&amp;quot;,
       &amp;quot;name&amp;quot;: &amp;quot;bertha&amp;quot;,
       &amp;quot;color&amp;quot;: &amp;quot;tabby&amp;quot;
   }]
}

&lt;/pre&gt;

      &lt;/td&gt;
   &lt;/tr&gt;
   &lt;tr&gt;
      &lt;td valign=&quot;top&quot;&gt;

&lt;p&gt;Ember-Data expects individual objects like this:&lt;/p&gt;
&lt;pre&gt; 
{
   cat: {
       &amp;quot;id&amp;quot;: &amp;quot;a01dfaa0&amp;quot;,
       &amp;quot;name&amp;quot;: &amp;quot;bertha&amp;quot;,
       &amp;quot;color&amp;quot;: &amp;quot;tabby&amp;quot;
   }
}
&lt;/pre&gt; 

      &lt;/td&gt;
      &lt;td&gt;&lt;/td&gt;
      &lt;td valign=&quot;top&quot;&gt;

&lt;p&gt;Usergrid returns individual objects like this:&lt;/p&gt;
&lt;pre&gt; 
{
   &amp;quot;id&amp;quot;: &amp;quot;a01dfaa0&amp;quot;,
   &amp;quot;type&amp;quot;: &amp;quot;cat&amp;quot;,
   &amp;quot;name&amp;quot;: &amp;quot;bertha&amp;quot;,
   &amp;quot;color&amp;quot;: &amp;quot;tabby&amp;quot;
}

&lt;/pre&gt; 

      &lt;/td&gt;
   &lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;You can see two differences above. Ember-Data expects JSON objects to be returned with a &amp;quot;type key&amp;quot; which you can see above: the &amp;quot;cats&amp;quot; field in the collection and the &amp;quot;cat&amp;quot; field in the individual object. Also, Ember-Data expects an object&amp;#39;s ID field to be named &amp;quot;id&amp;quot; but Usergrid returns it as &amp;quot;uuid.&amp;quot;&lt;/p&gt;

&lt;p&gt;The deal with these differences, the Checkin app extends Ember-Data&amp;#39;s &lt;code&gt;DS.RESTSerializer&lt;/code&gt;. Here&amp;#39;s the code:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;From app.js (&amp;lt;a href=&amp;quot;https://github.com/snoopdave/usergrid-ember/blob/v2/js/app.js#L75&amp;quot;
&amp;gt;Link)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;
App.ApplicationSerializer = DS.RESTSerializer.extend({

  // Extract Ember-Data array from Usergrid response
  extractArray: function(store, type, payload) {

    // Difference: Usergrid does not return wrapper object with 
    // type-key. So here we grab the Usergrid Entities and stick 
    // them under a type-key
    var typeKey = payload.path.substring(1);
    payload[ typeKey ] = payload.entities;

    // Difference: Usergrid returns ID in &amp;#39;uuid&amp;#39; field, Ember-Data 
    // expects &amp;#39;id&amp;#39;. So here we add an &amp;#39;id&amp;#39; field for each Entity, 
    // with its &amp;#39;uuid&amp;#39; value.
    for ( var i in payload.entities ) {
      if ( payload.entities[i] &amp;&amp; payload.entities[i].uuid ) {
        payload.entities[i].id = payload.entities[i].uuid;
      }
    }
    return this._super(store, type, payload);
  },

  // Serialize Ember-Data object to Usergrid compatible JSON format
  serializeIntoHash: function( hash, type, record, options ) {

    // Usergrid does not expect a type-key
    record.eachAttribute(function( name, meta ) {
      hash[name] = record.get(name);
    });

    return hash;
  }
});
&lt;/pre&gt;

&lt;p&gt;In the code above you can see how the &lt;code&gt;extractArray()&lt;/code&gt; method moves the &amp;quot;entities&amp;quot; collection returned by Usergrid into a type-key field as expected by Ember-Data and how it copies the &amp;quot;uuid&amp;quot; field to add the &amp;quot;id&amp;quot; field that Ember-Data expects. &lt;/p&gt;

&lt;p&gt;We also need to transform the data that Ember-Data sends to Usergrid. You can see this above in the &lt;code&gt;serializeInHash()&lt;/code&gt; function, which ensures that when data is POSTed or PUT to Usergrid, the type key is removed because that&amp;#39;s what Usergrid expects.&lt;/p&gt;


&lt;h3&gt;Implementing Add-Checkin&lt;/h3&gt;

&lt;p&gt;To implement Add-Checkin, I added an HTML template called &amp;quot;add-checkin&amp;quot; to Checkin&amp;#39;s index.html file. The template displays an Add-Checkin form with two fields: one for content and one for the location. Here&amp;#39;s what it looks like in all its modal glory:&lt;/p&gt;

&lt;br&gt;
&lt;p&gt;
&lt;img src=&quot;https://rollerweblogger.org/roller/mediaresource/5bc05437-f090-409e-90e4-c0fd978ea3ca&quot; alt=&quot;screenshot of add-checkin page&quot;&gt;
&lt;/p&gt;
&lt;br&gt;

&lt;p&gt;Both fields are simple strings (someday I&amp;#39;d like to extend Checkin to use location information from the browser). I won&amp;#39;t go into detail here, but it took a bit of research to figure out how to make a Bootstrap modal dialog work with Ember.js. Below you can see the add-checkin controller, which provides a &lt;code&gt;save()&lt;/code&gt; function to save a new checkin.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;From app.js (&amp;lt;a href=&amp;quot;https://github.com/snoopdave/usergrid-ember/blob/v2/js/app.js#L390&amp;quot;
&amp;gt;Link&lt;/b&gt;)&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;
App.AddCheckinModalController = Ember.ObjectController.extend({

  actions: {

    save: function( inputs ) {

      var content = inputs.content;
      var location = inputs.location;
      var target = this.get(&amp;quot;target&amp;quot;);

      var activity = this.store.createRecord( &amp;quot;NewActivity&amp;quot;, {
        content: content,
        location: location,
        verb: &amp;quot;checkin&amp;quot;,
        actor: {
          username: Usergrid.user.username
        }
      });

      activity.save().then(
        function( success ) { 
          alert(&amp;quot;Saved&amp;quot;); 
        },
        function( error ) { 
          alert(&amp;quot;Error &amp;quot; + error.responseJSON.error_description); 
        }
      ); 

    } 
  }
});
&lt;/pre&gt;

&lt;p&gt;In the code above you can see how easy it is to access Usergrid data via Ember-Data now that we&amp;#39;ve got our custom REST adapter and serializer in place. We create a new Activity with a call to &lt;code&gt;this.store.createRecord()&lt;/code&gt; and to save it all we need to do is &lt;code&gt; activity.save()&lt;/code&gt;.&lt;/p&gt;


&lt;h4&gt;Time to wrap up...&lt;/h4&gt;

&lt;p&gt;To sum things up, here are some closing thoughts and observations.&lt;/p&gt; 

&lt;ul&gt;
   &lt;li&gt;If you are considering JavaScript MVC frameworks, then Ember.js is definitely worthy of  your consideration. The documentation makes it easy to learn and the community is friendly and helpful.&lt;/li&gt;
   &lt;li&gt;It would be great for Usergrid to provide an Ember.js SDK that makes it really easy to build apps with Ember.js and Usergrid.&lt;/li&gt;
   &lt;li&gt;Ember-Data is an integral part of Ember.js, something that you need to do pretty much anything, but it is treated as a separate package with separate documentation. That is somewhat confusing for a new user.&lt;/li&gt;
   &lt;li&gt;Ember-Data does not include built-in form validation so if your app includes a large number of non-trivial  forms, then you may prefer AngularJS over Ember.js. 
   &lt;li&gt;There is a &lt;a href=&quot;https://github.com/dockyard/ember-validations&quot;&gt;form validation plugin&lt;/a&gt; for Ember.js, but it requires the experimental &lt;a href=&quot;http://www.ember-cli.com&quot;&gt;Ember-CLI&lt;/a&gt; utility. I tried to use it, but Ember-CLI was unpleasnt enough that I gave up.&lt;/li&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;I appreciate any feedback you might have about this article, the Usergrid-Ember project and Apache Usergrid. If you want to see how the whole Usergrid-Ember project fits together, find it on GitHub here: &lt;a href=&quot;https://github.com/snoopdave/usergrid-ember&quot;&gt;Usergrid-Ember&lt;/a&gt;. Next up, I&amp;#39;ll write about my experiences using Apache Shiro to replace Spring Security in Apache Roller.&lt;/p&gt;&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/usergrid-ember-part-1</id>
        <title type="html">Usergrid and Ember.js - part 1</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/usergrid-ember-part-1"/>
        <published>2015-01-20T09:39:47+00:00</published>
        <updated>2018-02-16T12:48:24+00:00</updated> 
        <category term="Web Development" label="Web Development" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="baas" scheme="http://roller.apache.org/ns/tags/" />
        <category term="emberjs" scheme="http://roller.apache.org/ns/tags/" />
        <category term="javascript" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;The next one of my &lt;a href=&quot;http://rollerweblogger.org/roller/entry/2014-side-projects&quot;&gt;2014 Side projects&lt;/a&gt; that I&#146;d like to share is Usergrid-Ember, an experiment and attempt to learn more about &lt;a href=&quot;http://emberjs.com&quot;&gt;Ember.js&lt;/a&gt; and &lt;a href=&quot;http://usergrid.incubator.apache.org&quot;&gt;Apache Usergrid&lt;/a&gt; by implementing the Checkin example from my Usergrid mobile development talk. If you&amp;#39;re interested in either Usergrid or JavaScript web development then I hope you&amp;#39;ll read on...&lt;/p&gt;


&lt;h4&gt;Why Ember.js?&lt;/h4&gt;

&lt;a href=&quot;http://emberjs.com&quot;&gt;&lt;img src=&quot;https://rollerweblogger.org/roller/mediaresource/87879b47-6b14-4c18-a17e-576a68bf62a0&quot; alt=&quot;Ember logo&quot; align=&quot;right&quot;&gt;&lt;/a&gt;

&lt;p&gt;Ember.js is one of the leading frameworks for building browser-based apps. It&amp;#39;s one of &lt;a href=&quot;http://www.infoq.com/research/top-javascript-mvc-frameworks&quot;&gt;many JavaScript Model View Controller (MVC) frameworks&lt;/a&gt;. Generally speaking, these frameworks let you define a set of routes or paths in your app, for example /index, /orders, /about, etc. and map each to some JavaScript code and HTML templates. Handling a route usually means using Ajax to grab some &#147;model&#148; data from a server and using a template to create an HTML &#147;view&#148; of the data that calls functions provided in a &amp;quot;controller&amp;quot; object.&lt;/p&gt;

&lt;p&gt;JavaScript MVC frameworks are not simple and each has its own learning curve. Is it really worth the learning time when you can do so much with a little library like jQuery?  For most projects I think the answer is yes. These frameworks force you to organize your code in a logical and consistent way, which is really important as projects grow larger, and they provide features that may save you a lot of development time.&lt;/p&gt;

&lt;p&gt;Based on what I&amp;#39;ve seen on the net and local meet-ups, the leading frameworks these days are Ember.js and AngularJS. After I saw &lt;a href=&quot;http://allthingsopen.org/talks/the-ember-js-framework-everything-you-need-to-know/&quot;&gt;Yehudi Katz&#146;s talk at All Things Open&lt;/a&gt;, I decided to spend some time learning Ember.js.&lt;/p&gt;


&lt;h4&gt;Getting started with Ember.js&lt;/h4&gt;

&lt;p&gt;The first thing you see when you visit the &lt;a href=&quot;http://emberjs.com&quot;&gt;Ember.js&lt;/a&gt; site is a big button that says &amp;quot;DOWNLOAD THE STARTER KIT&amp;quot; and so that is where I started. The Starter Kit is a, a minimal Ember.js project with about twenty JavaScript, HTML and CSS files. It&amp;#39;s a good way to start: small and simple.&lt;/p&gt;  

&lt;p&gt;&lt;b&gt;Ember.js Starter Kit files:&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;
&lt;img src=&quot;https://rollerweblogger.org/roller/mediaresource/208a9957-5c35-4376-824a-1839f1dd6e02&quot; alt=&quot;screenshot of Starter Kit directory layout&quot;&gt;
&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Sidebar: I do hope they keep the Starter Kit around when the new &lt;a href=&quot;http://www.ember-cli.com&quot;&gt;Ember-CLI&lt;/a&gt; tool matures. Ember-CLI generates too many magic boiler-plate files and sub-directories for somebody who is trying to understand the basics of the framework. And this is an interesting point of view: &lt;a href=&quot;https://ca.non.co.il/index.php/ember-cli-is-making-you-stupid/&quot;&gt;Ember-CLI is Making You Stupid&lt;/a&gt; by Yoni Yechezkel.&lt;/i&gt;&lt;/p&gt;


&lt;h4&gt;Other stuff: Bower, Grunt and Bootstrap&lt;/h4&gt;

&lt;p&gt;I like to bite off more than I can chew, so I decided to use a couple of other tools. I used &lt;a href=&quot;http://bower.io&quot;&gt;Bower&lt;/a&gt; to manage dependencies and &lt;a href=&quot;http://gruntjs.com&quot;&gt;Grunt&lt;/a&gt; to concatenate and minify those dependencies, and other things like launching a simple web server for development purposes. I also decided to use &lt;a href=&quot;http://getbootstrap.com&quot;&gt;Bootstrap&lt;/a&gt; to provide various UI components needed, like a navbar and nicely styled list views.&lt;p&gt;

&lt;p&gt;I won&amp;#39;t cover the details, but it was relatively easy to get Bower and Grunt working. Here are the config files in case you are interested: &lt;a href=&quot;https://github.com/snoopdave/usergrid-ember/blob/master/bower.json&quot;&gt;bower.json&lt;/a&gt; and &lt;a href=&quot;https://github.com/snoopdave/usergrid-ember/blob/master/Gruntfile.js&quot;&gt;Gruntfile.js&lt;/a&gt;. I did hit one problem: when I included Bootstrap as one of my dependencies the Glyphicons would all appear as tiny boxes, so I decided to pull Bootstrap from a CDN instead  (looks like there is a &lt;a href=&quot;https://github.com/twbs/bootstrap/issues/9940&quot;&gt;fix&lt;/a&gt; for that now).&lt;/p&gt;


&lt;h4&gt;Defining Index Route, Model and Template&lt;/h4&gt;

&lt;p&gt;Every Ember.js app needs to define some routes. There is a default route for the &amp;quot;/&amp;quot; path which is called the index route, and you can add your own routes using the Router object. The snippet below shows what I needed to get started:&lt;/p&gt;

&lt;b&gt;Part of app.js (&lt;a href=&quot;https://github.com/snoopdave/usergrid-ember/blob/v2/js/app.js#L18&quot;&gt;link&lt;/a&gt;)&lt;/b&gt;
&lt;pre class=&quot;brush: js;&quot;&gt;
// create the ember app object
App = Ember.Application.create();

// define routes
App.Router.map(function() {
    this.route(&amp;quot;login&amp;quot;, { path: &amp;quot;/login&amp;quot; });  
    this.route(&amp;quot;logout&amp;quot;, { path: &amp;quot;/logout&amp;quot; });
    this.route(&amp;quot;register&amp;quot;, { path: &amp;quot;/register&amp;quot; });
});
&lt;/pre&gt;

&lt;p&gt;Ember.js will look for the JavaScript Route and Controller objects as well as the HTML template using the names above. For example: Ember.js will expect the login route to be named &lt;code&gt;App.LoginRoute&lt;/code&gt;, the controller to be named &lt;code&gt;App.LoginController&lt;/code&gt; and the template to be named &amp;quot;login.&amp;quot;&lt;/p&gt;

&lt;p&gt;Let&amp;#39;s talk about the index route. When a user arrives at your app they&#146;ll be directed to the index route. Ember.js will then look for a JavaScript object called &lt;code&gt;App.IndexRoute&lt;/code&gt; to provide the model data and JavaScript functions needed for the index page. Here&#146;s a partial view of the index route:&lt;/p&gt;

&lt;b&gt;Part of app.js (&lt;a href=&quot;https://github.com/snoopdave/usergrid-ember/blob/v2/js/app.js#L175&quot;&gt;link&lt;/a&gt;)&lt;/b&gt;
&lt;pre class=&quot;brush: js;&quot;&gt;
App.IndexRoute = Ember.Route.extend( {

    // provide model data needed for index template
    model: function() {
        if ( this.loggedIn() ) {
            return this.store.find(&amp;quot;activity&amp;quot;);
        }
        return [];
    }

});
&lt;/pre&gt;

&lt;p&gt;The index page of the Checkin app shows the Checkin activities of the people that you follow. Above you can see how to route&amp;#39;s &lt;code&gt;model()&lt;/code&gt; function makes that data available to the template for display.  If the user is logged in we call the &lt;code&gt;store.find(&#147;activity&#148;)&lt;/code&gt; function to call the Usergrid REST API to get an array of the latest Activity objects. There is some serious Ember-Data magic going on there and I&amp;#39;ll cover that in part two of this article.&lt;/p&gt;

&lt;p&gt;To display the index route, Ember looks for an HTML template called &#147;index&#148; and will use that template to display the index page. Below is the index template. The template is a &lt;a href=&quot;http://handlebarsjs.com&quot;&gt;Handlebars&lt;/a&gt; template and the things that appear in double curly-braces are Handlebars expressions.&lt;/p&gt;

&lt;b&gt;Part of index.html (&lt;a href=&quot;https://github.com/snoopdave/usergrid-ember/blob/v2/index.html#L46&quot;&gt;link&lt;/a&gt;)&lt;/b&gt;
&lt;pre class=&quot;brush: js;&quot;&gt;


  
    &lt;div class=&quot;container-fluid&quot;&gt;

      &lt;div class=&quot;navbar-header&quot;&gt;
        Checkin
      &lt;/div&gt;

      
          {{action &amp;#39;showModal&amp;#39; &amp;#39;add-checkin-modal&amp;#39; model }}&amp;gt;Add Checkin
      

      &lt;ul class=&quot;nav navbar-nav navbar-right&quot;&gt;
        &lt;li&gt;Logout &lt;/li&gt;
      &lt;/ul&gt;

    &lt;/div&gt;
  

  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-md-12&quot;&gt;

      &lt;ul class=&quot;list-group&quot;&gt;
        {{#each item in model}}
          &lt;li class=&quot;list-group-item&quot;&gt;
              {{item.content}} | {{item.location}}
          &lt;/li&gt;
        {{/each}}
      &lt;/ul&gt;

    &lt;/div&gt;
  &lt;/div&gt;


&lt;/pre&gt;

&lt;p&gt;In the above template you can see a couple of &lt;code&gt;{{action}}&lt;/code&gt; expressions that call out to JavaScript methods defined in the Checkin app. The part of the code that uses the model is in the &lt;code&gt;{{#each}}&lt;/code&gt; loop which loops through each Activity in the model and dispays an HTML list with the the item.content and item.location of each Activity.&lt;/p&gt;

&lt;p&gt;Here&amp;#39;s what the above template looks like when displayed in a browser:&lt;/p&gt;

&lt;img src=&quot;https://rollerweblogger.org/roller/mediaresource/d052ee9f-4c60-44ea-b41a-b462b2bef876&quot; alt=&quot;screenshot of checkin app index page&quot;&gt;
&lt;br&gt;
&lt;br&gt;

&lt;h4&gt;Implementing Login&lt;/h4&gt;

&lt;p&gt;In Checkin, login is implemented using HTML Local Storage. Once a user has successfully logged in, the app stores the username and the user&amp;#39;s access_token in Local Storage. When user arrives at the index page, we check Local Storage to see if that user is logged in and if not, we direct them to the login route, which in turn displays the login page using the template below.&lt;/p&gt;

&lt;b&gt;Part of index.html (&lt;a href=&quot;https://github.com/snoopdave/usergrid-ember/blob/v2/index.html#L46&quot;&gt;link&lt;/a&gt;)&lt;/b&gt;
&lt;pre class=&quot;brush: js;&quot;&gt;


  
    &lt;div class=&quot;container-fluid&quot;&gt;
      &lt;div class=&quot;navbar-header&quot;&gt;
        Checkin
      &lt;/div&gt;
    &lt;/div&gt;
  

  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-md-3&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;col-md-6&quot;&gt;

        

         &lt;h2 class=&quot;form-login-heading&quot;&gt;Please Login&lt;/h2&gt;

         Email address
         {{input class=&amp;quot;form-control&amp;quot; type=&amp;quot;text&amp;quot; 
              valueBinding=&amp;quot;username&amp;quot; placeholder=&amp;quot;Username&amp;quot;}}

         Password
         {{input class=&amp;quot;form-control&amp;quot; type=&amp;quot;password&amp;quot; 
             valueBinding=&amp;quot;password&amp;quot; placeholder=&amp;quot;Password&amp;quot;}}
           
         
            Login
         

         Register as new user.
        

    &lt;/div&gt;
    &lt;div class=&quot;col-md-3&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;


&lt;/pre&gt;

&lt;p&gt;The LoginController provides the functions needed by the Login page itself and there are two. There is a &lt;code&gt;login()&lt;/code&gt; function (called on line 27 above) that performs the login, and there is a &lt;code&gt;register()&lt;/code&gt; function (called on line 31 above) that directs the user to the New User Registration page. Here&amp;#39;s a snippet of code from the &lt;code&gt;App.LoginController&lt;/code&gt; that provides these two functions:&lt;/p&gt;

&lt;b&gt;Part of app.js (&lt;a href=&quot;https://github.com/snoopdave/usergrid-ember/blob/v2/js/app.js#L250&quot;&gt;link&lt;/a&gt;)&lt;/b&gt;
&lt;pre class=&quot;brush: js;&quot;&gt;
App.LoginController = Ember.Controller.extend({

  actions: {

    login: function() { 

      // login by POST to Usergrid app&amp;#39;s /token end-point

      var loginData = {
        grant_type: &amp;quot;password&amp;quot;,
        username: this.get(&amp;quot;username&amp;quot;),
        password: this.get(&amp;quot;password&amp;quot;)
      };

      $.ajax({
        type: &amp;quot;POST&amp;quot;,
        url: Usergrid.getAppUrl() + &amp;quot;/token&amp;quot;,
        data: loginData,
        context: this,
        error: function( data ) {

          // login failed, show error message
          alert( data.responseJSON.error_description );
        },
        success: function( data ) { 

          // store access_token in local storage
          Usergrid.user = data.user;
          localStorage.setItem(&amp;quot;username&amp;quot;, loginData.username );
          localStorage.setItem(&amp;quot;access_token&amp;quot;, data.access_token );

          // clear the form
          this.set(&amp;quot;username&amp;quot;, &amp;quot;&amp;quot;); 
          this.set(&amp;quot;password&amp;quot;, &amp;quot;&amp;quot;);

         // call route to handle post-login transition
          this.get(&amp;quot;target&amp;quot;).send(&amp;quot;onLogin&amp;quot;); 
        }
      });
    },

    register: function() {
      this.transitionToRoute(&amp;quot;register&amp;quot;);
    }

  }
});
&lt;/pre&gt;

&lt;p&gt;The above code shows how to login to a Usergrid app using jQuery&amp;#39;s Ajax feature. The &lt;code&gt;login()&lt;/code&gt; function takes the username and password values from the login form, puts those in a JSON object with grant_type &amp;quot;password&amp;quot; and posts that object to the &lt;code&gt;/token&lt;/code&gt; end-point of the Usergrid app. If that post succeeds, the response will include an access_token. We store that in Local Storage; we&amp;#39;ll need to use it in all subsequent calls to Usergrid.&lt;/p&gt;

&lt;p&gt;Usergrid fans will notice that I&amp;#39;m not using the &lt;a href=&quot;https://github.com/snoopdave/incubator-usergrid/tree/master/sdks/html5-javascript&quot;&gt;Usergrid JavaScript SDK&lt;/a&gt;. That&amp;#39;s because Ember.js provides Ember-Data, which acts as a very nice REST client and can be adapted to work with the URL structure and JSON formats of just about any REST API. I&amp;#39;ll write about that in part two of this article.&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/2014-side-projects</id>
        <title type="html">2014 side projects</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/2014-side-projects"/>
        <published>2015-01-05T08:37:04+00:00</published>
        <updated>2018-02-16T12:57:41+00:00</updated> 
        <category term="Open Source" label="Open Source" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="javascript" scheme="http://roller.apache.org/ns/tags/" />
        <category term="usergrid" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">
&lt;p&gt;For various reasons, I&amp;#39;ve always got a couple of coding projects on the back burner, things that I hack around with on weekends and breaks. In 2014, I started four projects and learned about Ember.js, jQuery Mobile, Apache Shiro, Apache CXF and the Arquillian test framework. &lt;/p&gt;


&lt;p&gt;I like to share my code, so I&amp;#39;ve put my code on GitHub and I&amp;#39;m going to write a brief post about each here on my blog. I&amp;#39;ll provide links as I go and, of course, I welcome any criticisms and suggestions for improvement that you might have. First up: the Usergrid-Mobile project.&lt;/p&gt;


&lt;p&gt;&lt;h3&gt;The Usergrid-Mobile project&lt;/h3&gt;&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;https://rollerweblogger.org/roller/mediaresource/128ca398-027d-491d-9e0b-b24c77c8e9b9&quot; alt=&quot;ApacheCon EU logo&quot; align=&quot;right&quot; height=&quot;100&quot;&gt;&lt;br&gt;
To be honest, Budapest was the goal of this project. In the Spring of 2014, I decided that the best chance of getting to ApacheCon EU in Budapest was to create a great &amp;quot;mobile development with Usergrid&amp;quot; talk, and to do that I needed a great example project. The resulting project shows how to create a dumbed-down Foursquare-style &amp;quot;checkin&amp;quot; app using HTML5, JavaScript, &lt;a href=&quot;http://jquerymobile.com&quot;&gt;jQuery Mobile&lt;/a&gt; and &lt;a href=&quot;http://cordova.apache.org&quot;&gt;Apache Cordova&lt;/a&gt;. &lt;/p&gt;


&lt;p&gt;Luckily for me, my talk was &lt;a href=&quot;http://apacheconeu2014.sched.org/event/edbc9c695e39c2960441690a8a23b5d3#.VKceecaZ7tE&quot;&gt;accepted&lt;/a&gt; for ApacheCon EU and in November I traveled to Budapest (took some &lt;a href=&quot;https://www.flickr.com/photos/snoopdave/15859954201/in/set-72157649019765409&quot;&gt;photos&lt;/a&gt;) and gave the talk there. &lt;/p&gt;


&lt;p&gt;I also presented the talk at the All Things Open conference in Raleigh, NC and you can view a video of that talk, &lt;a href=&quot;https://www.youtube.com/watch?v=DjFG-QbxxLw&quot;&gt;Mobile Development with Usergrid&lt;/a&gt; on YouTube.&lt;/p&gt;


&lt;p&gt;&lt;p&gt;&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;&lt;/p&gt;


&lt;p&gt;You can find the code for &lt;a href=&quot;https://github.com/snoopdave/usergrid-mobile&quot;&gt;usergrid-mobile&lt;/a&gt; on  GitHub. I also created a Vagrant File to launch a local instance of Usergrid for demo purposes. It&amp;#39;s called usergrid-vagrant.&lt;/p&gt;


&lt;p&gt;That&amp;#39;s all for now. Next up: Usergrid-Ember.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/phoenix-websites</id>
        <title type="html">Phoenix Websites</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/phoenix-websites"/>
        <published>2014-12-01T07:07:25+00:00</published>
        <updated>2018-02-16T12:44:56+00:00</updated> 
        <category term="Web Development" label="Web Development" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="business" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;http://phoenixrdu.com&quot;&gt;

&lt;/a&gt;

&lt;p&gt;My eldest son Alex and his friend Austin have started a website design and creation business called &lt;a href=&quot;http://phoenixrdu.com&quot;&gt;Phoenix Websites&lt;/a&gt; and, of course, I think this is a great thing. They&amp;#39;re not yet out of high school and just getting started, but they&amp;#39;ve already landed a couple of real live customers. They&amp;#39;ve got some skills and are not afraid of hard work, so if you&amp;#39;re a Triangle-area small business owner and you need a nice new website, check them out. &lt;/p&gt;

&lt;p&gt;Like any new business, they need some link love so here we go: &lt;a href=&quot;http://phoenixrdu.com&quot;&gt;Phoenix Websites: Website design and creation services in the Raleigh-Durham Triangle-area&lt;/a&gt;.  Follow them on twitter at &lt;a href=&quot;http://twitter.com/phoenixrdu&quot;&gt;@phoenixrdu&lt;/a&gt;&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/introduction-to-apache-usergrid</id>
        <title type="html">Introduction to Apache Usergrid</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/introduction-to-apache-usergrid"/>
        <published>2014-11-29T10:09:48+00:00</published>
        <updated>2018-02-16T12:44:49+00:00</updated> 
        <category term="Open Source" label="Open Source" />
        <category term="apache" scheme="http://roller.apache.org/ns/tags/" />
        <category term="apachecon" scheme="http://roller.apache.org/ns/tags/" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="baas" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;I travelled to Budapest, Hungary for a couple of weeks for a very nice &lt;a href=&quot;https://www.flickr.com/photos/snoopdave/sets/72157649019765409/&quot;&gt;vacation&lt;/a&gt; with my wife and to speak at ApacheCon EU. Here are the slides that I presented at ApacheCon EU:&lt;/p&gt;

&lt;br&gt;

  

&lt;br&gt;

&lt;p&gt;(you can also &lt;a href=&quot;http://www.slideshare.net/snoopdave/introduction-to-usergrid-apache-con-eu-2014&quot;&gt;view the presentation on Slideshare&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;And here is the session abstract:&lt;/p&gt;

&lt;p&gt;Whether you are building a mobile app or a web app, Apache Usergrid (incubating) can provide you with a complete backend that supports authentication, persistence and social features like activities and followers all via a comprehensive REST API &#151; and backed by Cassandra, giving you linear scalability. All that, and Usergrid is open source too. &lt;/p&gt;

&lt;p&gt;This session will explain how you can use Usergrid to provide a back-end for your application. We&#146;ll start with an overview of Usergrid features, then explore in depth how to authenticate users, store data and query data with the REST API provided by a Usergrid server. We&#146;ll develop a simple HTML5 app and package it as a native mobile app via Apache Cordova. We&amp;#39;ll also cover how to run Usergrid locally for development and testing.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/talking_usergrid_at_apachecon2014</id>
        <title type="html">Talking Usergrid at ApacheCon 2014</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/talking_usergrid_at_apachecon2014"/>
        <published>2014-03-16T16:10:16+00:00</published>
        <updated>2018-02-16T12:47:05+00:00</updated> 
        <category term="Open Source" label="Open Source" />
        <category term="apachecon" scheme="http://roller.apache.org/ns/tags/" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="baas" scheme="http://roller.apache.org/ns/tags/" />
        <category term="cassandra" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="opensource" scheme="http://roller.apache.org/ns/tags/" />
        <category term="usergrid" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;http://www.apachecon.com/&quot;&gt;
&lt;img src=&quot;https://rollerweblogger.org/roller/mediaresource/59d5e8f1-074f-4fd2-84a3-0b0a108c089c&quot; align=&quot;right&quot; alt=&quot;ApacheCon 2014&quot;&gt;
&lt;/a&gt;

&lt;p&gt;I&amp;#39;ve been working at &lt;a href=&quot;http://apigee.com&quot;&gt;Apigee&lt;/a&gt; since September 2013 and one of the things I love most about my new job is the fact that I&amp;#39;m actively contributing to open source again. &lt;/p&gt;

&lt;p&gt;I&amp;#39;m working on &lt;a href=&quot;http://usergrid.incubator.apache.org/&quot;&gt;Apache Usergrid&lt;/a&gt; (incubating), an open source &lt;b&gt;Backend-As-A-Service&lt;/b&gt; (BaaS) that&amp;#39;s built on the Apache Cassandra database system. Apigee uses Usergrid as part of &lt;a href=&quot;http://apigee.com/about/content/apigee-edge&quot;&gt;Apigee Edge&lt;/a&gt; (see the &lt;a href=&quot;http://apigee.com/docs/content/build-apps-home&quot;&gt;Build Apps&lt;/a&gt; part of the docs).&lt;/p&gt;

&lt;p&gt;Apigee contributed code for Usergrid to the &lt;a href=&quot;http://apache.org&quot;&gt;Apache Software Foundation&lt;/a&gt; back in October 2013 and Usergrid is now part of the Apache Incubator. The project is working towards graduating from the Incubator. That means learning the Apache way, following the processes to get a release out and most importantly, building a diverse community of contributors to build and maintain Usergrid.&lt;/p&gt;

&lt;p&gt;One on the most important parts of building an open source community is making it easy for people to contribute and and that&amp;#39;s why I submitted a talk to the &lt;a href=&quot;http://www.apachecon.com/&quot;&gt;ApacheCon US 2014&lt;/a&gt; conference (April 7-9 in Denver, CO) titled &lt;a href=&quot;http://events.linuxfoundation.org/events/apachecon-north-america/program/schedule&quot;&gt;How to Contribute to Usergrid&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The talk is intended to be a briefing for contributors, one that will lead you through building and running Usergrid locally, understanding the code-base and test infrastructure and how to get your code accepted into the Usergrid project.&lt;/p&gt;

&lt;p&gt;Here&amp;#39;s the outline I have so far:&lt;/p&gt;

&lt;h3&gt;How to Contribute to Apache Usergrid&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Motivation
    &lt;ul&gt;&lt;li&gt;Why would anybody want to contribute to Usergrid?&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;First steps
    &lt;ul&gt;&lt;li&gt;The basics&lt;/li&gt;&lt;/ul&gt;
    &lt;ul&gt;&lt;li&gt;Getting signed up&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Contributing to the Stack
    &lt;ul&gt;&lt;li&gt;Understanding the architecture &amp; code base&lt;/li&gt;&lt;/ul&gt;
    &lt;ul&gt;&lt;li&gt;Building the code. Making and testing changes&lt;/li&gt;&lt;/ul&gt;
    &lt;ul&gt;&lt;li&gt;Running Usergrid locally via launcher &amp; via Tomcat&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Contributing to the Portal
    &lt;ul&gt;&lt;li&gt;Understanding the architecture &amp; code base&lt;/li&gt;&lt;/ul&gt;
    &lt;ul&gt;&lt;li&gt;Building the code. Making and testing changes&lt;/li&gt;&lt;/ul&gt;
    &lt;ul&gt;&lt;li&gt;Running the portal locally via node.js&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Contributing to the SDKs
    &lt;ul&gt;&lt;li&gt;Understanding the architecture &amp; code base&lt;/li&gt;&lt;/ul&gt;
    &lt;ul&gt;&lt;li&gt;Building the code. Making and testing changes&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Contributor workflow: how to get your code into Usergrid
    &lt;ul&gt;&lt;li&gt;For quickie drive-by code contributions&lt;/li&gt;&lt;/ul&gt;
    &lt;ul&gt;&lt;li&gt;For more substantial code contributions&lt;/li&gt;&lt;/ul&gt;
    &lt;ul&gt;&lt;li&gt;For documentation &amp;  website changes&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Contributing Docs and Website changes
    &lt;ul&gt;&lt;li&gt;Website, wiki and GitHub pages&lt;/li&gt;&lt;/ul&gt;
    &lt;ul&gt;&lt;li&gt;How to build the website and docs&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Roadmap
    &lt;ul&gt;&lt;li&gt;First release&lt;/li&gt;&lt;/ul&gt;
    &lt;ul&gt;&lt;li&gt;New Core Persistence system&lt;/li&gt;&lt;/ul&gt;
    &lt;ul&gt;&lt;li&gt;The two-dot-o branch&lt;/li&gt;&lt;/ul&gt;
    &lt;ul&gt;&lt;li&gt;Other ideas&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I&amp;#39;m in the process of writing this talk now so suggestions and other feedback are most welcome.&lt;/p&gt;


</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/how_wayin_does_orchestration</id>
        <title type="html">How Wayin does Cloud Orchestration</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/how_wayin_does_orchestration"/>
        <published>2013-06-18T16:16:34+00:00</published>
        <updated>2018-02-16T12:46:49+00:00</updated> 
        <category term="Web Development" label="Web Development" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="aws" scheme="http://roller.apache.org/ns/tags/" />
        <category term="cloud" scheme="http://roller.apache.org/ns/tags/" />
        <category term="devops" scheme="http://roller.apache.org/ns/tags/" />
        <category term="orchestration" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wayin" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;I&amp;#39;ve already mentioned this on Twitter and LinkedIn, but just in case you missed it: I&amp;#39;ll be speaking tomorrow night at the &lt;a href=&quot;http://www.meetup.com/Triangle-DevOps/events/121662952&quot;&gt;Triangle AWS and Triangle DevOps&lt;/a&gt; joint meetup at &lt;a href=&quot;http://argylesocial.com/&quot;&gt;Argyle Social&lt;/a&gt; in Durham, NC. I&amp;#39;ll give a quick overview of cloud orchestration and &lt;a href=&quot;http://wayinhub.com&quot;&gt;Wayin Hub&lt;/a&gt;. Then I&amp;#39;ll dive into the details of how we automate deployment, scaling and backups for Wayin Hub using AWS and AWS Cloud Formation.&lt;/p&gt;

&lt;p&gt;As a little teaser, here&amp;#39;s a GIF animation of my automated deployment slide:&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;

&lt;p&gt;For more information check the &lt;a href=&quot;http://www.meetup.com/Triangle-DevOps/events/121662952&quot;&gt;Triangle DevOps page&lt;/a&gt; for the event.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;UPDATE: &lt;/b&gt; slide are now on &lt;a href=&quot;http://www.slideshare.net/snoopdave/wayin-devops2013&quot;&gt;SlideShare&lt;/a&gt;.&lt;/p&gt;

</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/composite_keys_in_cassandra</id>
        <title type="html">Composite Keys in Apache Cassandra</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/composite_keys_in_cassandra"/>
        <published>2013-05-23T17:56:49+00:00</published>
        <updated>2013-05-24T16:08:47+00:00</updated> 
        <category term="Open Source" label="Open Source" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="bigdata" scheme="http://roller.apache.org/ns/tags/" />
        <category term="cassandra" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wayin" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wayinhub" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;Newer versions of &lt;a href=&quot;http://cassandra.apache.org&quot;&gt;Apache Cassandra&lt;/a&gt; include &lt;a href=&quot;http://cassandra.apache.org/doc/cql3/CQL.html&quot;&gt;CQL&lt;/a&gt;, an SQL-like query language that supports both query, update and delete statements as well as the Data Definition Language (DDL) statements like create and alter for tables and indexes. You can create tables (known as column families in Cassandra lingo) just like you can in a relational database, but there are some caveats.&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;Newer versions of &lt;a href=&quot;http://cassandra.apache.org&quot;&gt;Apache Cassandra&lt;/a&gt; include &lt;a href=&quot;http://cassandra.apache.org/doc/cql3/CQL.html&quot;&gt;CQL&lt;/a&gt;, an SQL-like query language that supports both query, update and delete statements as well as the Data Definition Language (DDL) statements like create and alter for tables and indexes.&lt;/p&gt;

&lt;p&gt;You can create tables (known as column families in Cassandra lingo) just like you can in a relational database, but there are some caveats. One caveat is this: if you want to sort and use ORDER BY in queries on a table, then you will have to use composite-key in that table and that composite key must include the field that you wish to sort on. You have to decide which fields you wish to sort on when you design your data model, not when you formulate queries. Another caveat is that, with Cassandra 1.1, there is no support for secondary indexes on composite-keyed tables. That means you can only query on the fields in the composite-key and in certain specific ways. More on that later.&lt;/p&gt;

&lt;p&gt;In version 1.1, Cassandra supports (at least) two different models for storing data. You can use a single primary key in your table, or you can use a composite key. Cassandra stores your data differently for these two cases and the queries that you can perform on these two types of tables vary as well. &lt;/p&gt;

&lt;p&gt;I&#146;ll explain how simple-keyed and composite-keyed differ with some examples. The example is the Bite table, which holds a chunk of data identified by an ID and sorted by an integer score value. I don&#146;t want to get into details, but in the product I&amp;#39;m working on, &lt;a href=&quot;http://www.wayin.com/products/wayin-hub&quot;&gt;Wayin Hub&lt;/a&gt;, a Site contains Feeds and Feeds contain Bites, which might represent Tweets, RSS items or other social network activities. Hopefully, that will be enough background for you to understand the examples below.

&lt;h3&gt;Single-keyed Table&lt;/h3&gt;

&lt;p&gt;With a single keyed table you have a row for each entity that you store and a column in that row for each field of the entity. For example, to represent the Bite table as a single-keyed table it would be defined like so:&lt;/p&gt;

&lt;pre&gt;

   create table bite (
	id varchar PRIMARY KEY,
	feedid varchar,
	score bigint,
	data varchar
   );

   create index bite_feedid on bite (feedid);
   create index bite_score on bite (score);

&lt;/pre&gt;

&lt;p&gt;We need those id, feedid and score fields so we can look up bites by those values. The data field is used to store a JSON representation of other data we associate with each Bite. For example, if you only have three Bites in the table, here&#146;s what the results of a select * from bite might look like:&lt;/p&gt;

&lt;pre&gt;

 id   |  feedid  |  score  | data
------+----------+---------+----------------------
bite2 |  feed0   |   101   | { &#147;status&#148; : &#147;APPROVED&#148;, ... 
bite3 |  feed0   |   102   | { &#147;status&#148; : &#147;DENIED&#148;, ...
bite1 |  feed0   |   100   | { &#147;status&#148; : &#147;APPROVED&#148;, ...  

&lt;/pre&gt;

&lt;p&gt;The way the data is stored in Cassandra would look about the same, as illustrated in the diagram below. Each table row corresponds to a Row in Cassandra, the id of the table row is the Cassandra Row Key for the row. Each value in the row is a Cassandra Column with a key and a value. If you add more table rows, you get more Cassandra Rows.&lt;/p&gt;

&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/fcac32c5-6a8d-4be9-acfa-1e56389c6c4c&quot;&gt;

&lt;p&gt;Now let&#146;s get back to the topic of this post and that caveat that I mentioned earlier.&lt;/p&gt;

&lt;h3&gt;Composite-keyed Table &lt;/h3&gt;

&lt;p&gt;If we want to sort data in a table, then we need to use a composite-keyed table.  With a composite-keyed table you define a composite-key made up of multiple fields from the table. The first key is known as the partition-key. To sort by score we also include the score in the composite key. And since it is possible for two Bites with the same partition key to occur at the very same time, we also include varchar ID to ensure uniqueness.&lt;p&gt;

&lt;p&gt;Here&#146;s how the Bite table is defined. The composite-key is the list of three fields in PRIMARY KEY parentheses.&lt;/p&gt;

&lt;pre&gt;

   create table Bite (
	 partkey varchar,
	 score bigint,
	 id varchar,
	 data varchar,
	 PRIMARY KEY (partkey, score, id)
   ) with clustering order by (score desc);

&lt;/pre&gt;

&lt;p&gt;And if you had three Bites in the table the query select * from bite would return this:&lt;/p&gt;

&lt;pre&gt;

 partkey  |  score  |  id   |  data
----------+---------+-------+----------------------
  feed0   |   102   | bite3 | { &#147;id&#148; : &#147;bite2&#148;, ... 
  feed0   |   101   | bite2 | { &#147;id&#148; : &#147;bite3&#148;, ...
  feed0   |   100   | bite1 | { &#147;id&#148; : &#147;bite1&#148;, ...  

&lt;/pre&gt;

&lt;p&gt;The surprise is how this table is stored in Cassandra. Instead of storing a Cassandra Row for each table row, the data is stored as one row. The more Bites you add to the table, the more Cassandra Columns are added to that Row. The diagram below illustrates how this works for the three Bites of data above. There is one Row with key of feed0. And there is one Column for each table row of data. Each Column uses a key that combines the score and id plus a string that indicates what field is stored in the Column Value, which in our case is only the data field.&lt;/p&gt;

&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/255341b2-0705-47b1-9d3b-9725cb140566&quot;&gt;

&lt;h3&gt;Querying a Composite-keyed Table&lt;/h3&gt;

&lt;p&gt;With Cassandra 1.1, if you want to select a single Bite, you must know all of the composite-keys. Here&#146;s an example query that selects a single Bite:&lt;/p&gt;

&lt;pre&gt;

   select data from bite where partkey=&#146;feed0&#146; and score=101 and id=&#146;bite2&#146;

&lt;/pre&gt;

&lt;p&gt;To get latest Bites in a Site&#146;s Feed, you specify only the partition-key and ask for ordering by score, like so:&lt;/p&gt;

&lt;pre&gt;

   select data from bite where partkey=&#146;feed0&#146; order by score desc limit 20

&lt;/pre&gt;

&lt;p&gt;If you try to query without specifying the partition key and the score, you will get an error message. For example, this query:&lt;/p&gt;

&lt;pre&gt;

   select data from bite where id=&#146;bite2&#146; limit 20

&lt;/pre&gt;

&lt;p&gt;Would give you this error message:&lt;/p&gt;

   &lt;pre&gt;

   Bad Request: PRIMARY KEY part id cannot be restricted (preceding
   part score is either not restricted or by a non-EQ relation)

   &lt;/pre&gt;

&lt;p&gt;That means we can&#146;t look up Bites by a single ID. That&#146;s not very convenient but that&#146;s the way it is with Cassandra 1.1 which does not allow additional indexes on composite-key tables.. If you really want to lookup Bites by id, you have to create an entirely new simple-keyed table with Bite id as the primary key and use that table to look up the a Bite&#146;s partKey and score. This problem is fixed in Cassandra 1.2 because it allows secondary indexes on fields in composite-key table. Let&#146;s talk about that.&lt;/p&gt;

&lt;h3&gt;Secondary Indexes&lt;/h3&gt;

&lt;p&gt;Cassandra 1.2 comes with support for secondary indexes on composite-keyed tables, but you cannot create a secondary index on keys that are already part of the composite-key. So, if we want to be able to look-up Bites by ID, then we must add a second and redundant biteid field like so:&lt;/p&gt;

   &lt;pre&gt;

   alter table Bite add biteId varchar;
   create index Bite_biteId on Bite (biteId); 

   &lt;/pre&gt;

&lt;p&gt;Inside Cassandra, the the data would look like this, a new field in the table means a new Column in the row, as show below:&lt;/p&gt;

&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/8215a60a-add0-4f38-9849-c4097bc25331&quot;&gt;

&lt;p&gt;And with that secondary index we can support queries like this:&lt;/p&gt;

   &lt;pre&gt;

   select data from bite where biteid=&#146;bite2&#146;

   &lt;/pre&gt;

&lt;h3&gt;Cassandra 1.2&lt;/h3&gt;

&lt;p&gt;In the DataStax Cassandra 1.2 docs, it says &#147;CQL3 transposes data partitions (sometimes called &amp;quot;wide rows&amp;quot;) into familiar row-based result sets, dramatically simplifying data modeling. &lt;/p&gt;

&lt;p&gt;I believe that means that all tables are stored the way that composite-keyed tables are stored. According to the docs, legacy tables from Cassandra 1.1 are supported in 1.2 and, if you want, you can still create Cassandra 1.1 style tables by using the &#147;compact storage&#148; attribute. For example, to create the Bite table with a the Cassandra 1.1 table model and a single primary key you&#146;d do this: &lt;/p&gt;

&lt;pre&gt;

   create table bite (
	id varchar PRIMARY KEY,
	feedid varchar,
	score bigint,
	data varchar
   ) with compact storage;

&lt;/pre&gt;

&lt;p&gt;And that&#146;s all I&#146;ve got on this topic.&lt;/p&gt;

&lt;h3&gt;Wrapping up...&lt;/h3&gt;

&lt;p&gt;I wrote this up to help myself understand how composite-keyed tables work in Cassandra, so I&#146;d love any feedback you might have and especially if you think I&#146;ve got concepts or terminology wrong. Thanks for reading.&lt;/p&gt;


&lt;p&gt;You can read more about Cassandra 1.1 tables on the Datastax site:&lt;br&gt;
&lt;a href=&quot;http://www.datastax.com/docs/1.1/ddl/column_family&quot;&gt;http://www.datastax.com/docs/1.1/ddl/column_family&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More about Cassandra 1.2 tables:&lt;br&gt;
&lt;a href=&quot;http://www.datastax.com/docs/1.2/ddl/table&quot;&gt;http://www.datastax.com/docs/1.2/ddl/table&lt;/a&gt;&lt;p&gt;

&lt;p&gt;More about Cassandra 1.1 legacy tables in Cassandra 1.2&lt;br&gt;
&lt;a href=&quot;http://www.datastax.com/docs/1.2/ddl/legacy_table&quot;&gt;http://www.datastax.com/docs/1.2/ddl/legacy_table&lt;/a&gt;&lt;p&gt;

&lt;p&gt;Also, I found these posts by Brian O&#146;Neill very helpful:&lt;br&gt;
http://brianoneill.blogspot.com/2012/09/composite-keys-connecting-dots-between.html &lt;br&gt;
http://brianoneill.blogspot.com/2012/10/cql-astyanax-and-compoundcomposite-keys.html&lt;/p&gt;

&lt;br&gt;
&lt;p&gt;
   &lt;a href=&quot;http://wayin.com&quot;&gt;
      &lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/f624dfcd-2f04-406b-a2b2-f2bc1fa1afbe&quot;&gt;
   &lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;And, if you want to build an engaging site for your customers, fans or constituents based on live tweets, photos and videos check out &lt;a href=&quot;http://www.wayin.com/products/wayin-hub&quot;&gt;Wayin Hub&lt;/a&gt; and follow &lt;a href=&quot;https://twitter.com/wayinhub&quot;&gt;@wayinhub&lt;/a&gt; on Twitter.&lt;/p&gt;

&lt;br&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/wip_widgets_and_gadgets</id>
        <title type="html">WIP: Widgets and Gadgets</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/wip_widgets_and_gadgets"/>
        <published>2012-02-22T07:52:11+00:00</published>
        <updated>2012-09-15T18:45:01+00:00</updated> 
        <category term="Web Development" label="Web Development" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gadgets" scheme="http://roller.apache.org/ns/tags/" />
        <category term="widgets" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;&lt;i&gt;This is the fifth in my series of Web Integration Patterns. Check out the intro at this URL &lt;a href=&quot;http://rollerweblogger.org/roller/entry/web_integration_patterns&quot;&gt;http://rollerweblogger.org/roller/entry/web_integration_patterns&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;

&lt;h3&gt;Synopsis&lt;/h3&gt; 

&lt;p&gt;
Allow other web sites and applications to integrate your site into their web pages by providing an embeddable user interface, commonly known as a Gadget or Widget, which allows users to view and interact with your site in the context of other sites.
&lt;/p&gt;

&lt;h3&gt;Motivations&lt;/h3&gt;
&lt;ul&gt;
   &lt;li&gt;By embedding Widgets in your site, you can make your site more useful and informative to your users. Users can access relevant information from other sites in the context of your web site.&lt;/li&gt;

   &lt;li&gt;By allow other sites to embed your Widgets, you can give your site and the services that it offers wider reach. Your users can access and interact with your services in the context of other sites.&lt;/li&gt;
&lt;/ul&gt;</summary>
        <content type="html">&lt;p&gt;&lt;i&gt;This is the fifth in my series of Web Integration Patterns. Check out the intro at this URL &lt;a href=&quot;http://rollerweblogger.org/roller/entry/web_integration_patterns&quot;&gt;http://rollerweblogger.org/roller/entry/web_integration_patterns&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;

&lt;h3&gt;Synopsis&lt;/h3&gt; 

&lt;p&gt;
Allow other web sites and applications to integrate your site into their web pages by providing an embeddable user interface, commonly known as a Gadget or Widget, which allows users to view and interact with your site in the context of other sites.
&lt;/p&gt;

&lt;h3&gt;Motivations&lt;/h3&gt;
&lt;ul&gt;
   &lt;li&gt;By embedding Widgets in your site, you can make your site more useful and informative to your users. Users can access relevant information from other sites in the context of your web site.&lt;/li&gt;

   &lt;li&gt;By allow other sites to embed your Widgets, you can give your site and the services that it offers wider reach. Your users can access and interact with your services in the context of other sites.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Related Patterns&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Dashboards and Portals&lt;/li&gt;
&lt;li&gt;Social Network Plugins&lt;/li&gt;
&lt;li&gt;Delegated Pickers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
A Widget or Gadget is a piece of an application, a visual component or a chunk of user-interface  that can be added to some other application. On the web, Widgets are implemented using HTML and JavaScript, or sometimes Flash. Here we&amp;#39;ll discuss simple Widgets and leave discussion or more advanced usage of Widgets in Dashboards, Portals and Pickers for the more advanced patterns we&amp;#39;ll discuss later.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Easy to &amp;quot;consume&amp;quot;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
Widgets are easy, especially for widget &amp;quot;consumers&amp;quot; i.e. those who wish to add an existing Widget to their site. Adding a widget to your site or web application can be as easy as adding a couple of lines of HTML and JavaScript to the pages of your site. You can see some examples of Widgets in the two screen shots I&amp;#39;ve included here, below is the &lt;a href=&quot;http://wayin.com&quot;&gt;Wayin&lt;/a&gt; polling Widget, which shows my latest Wayins:
&lt;/p&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;

&lt;p&gt;

&lt;p&gt;
And below is the &lt;a href=&quot;http://flickr.com&quot;&gt;Flickr&lt;/a&gt; Widget, which shows a random selection of my photos from Flickr. You can see these two Widgets in action on the &lt;a href=&quot;http://rollerweblogger.org/roller&quot;&gt;front page of my blog&lt;/a&gt;. And, by the way, the Like, Tweet and +1 buttons on the right of this entry (when viewed on my blog site) are also Widgets.
&lt;/p&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;

&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Relatively easy to create&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Developing an entirely new Widget more complicated than using one that already exists. Creating a new Widget typically requires writing HTML and JavaScript code and employing some interesting tricks. The simplest way to implement a Widget is to use an iframe, allowing a portion of one site to be embedded in another site.&lt;/p&gt;

&lt;p&gt;I&amp;#39;m not going to go into detail as there are already so many good resources on the web for learning about Widget crafting. For example, Alex Marandon wrote a &lt;a href=&quot;http://alexmarandon.com/articles/web_widget_jquery/&quot;&gt;pretty comprehensive blog post on creating Widgets&lt;/a&gt; covering  basic issues like how to ensure that your widget code does not interfere with the page hosting the Widget, how to dynamically load resources and how to bypass browsers&#146; single-origin policy using JSON-P.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Widget and Gadget standards&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
For simple Widgets you don&amp;#39;t really need any standards other than HTML and JavaScript. If you want to target specific web site Dashboards or Portals, like NetVibes, or enterprise web applications like Jive or Atlassian&amp;#39;s software development tools, then you&amp;#39;ll need to create your Widgets with specific APIs in mind. For example, &lt;a href=&quot;http://dev.netvibes.com/doc/&quot;&gt;NetVibes&lt;/a&gt; provides it&amp;#39;s own Widget API, while Jive and Atlassian support the &lt;a href=&quot;http://code.google.com/apis/opensocial/&quot;&gt;Open Social Gadget APIs&lt;/a&gt;. I&amp;#39;ll talk more about these issues when I cover the related patterns Dashboards, Portals and Social Network Plugins.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Wrapping up...&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;That&amp;#39;s it for Widgets and Gadgets. Next up: Feed-based Integration.&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/rollarcus_9_to_2</id>
        <title type="html">Rollarcus: from 9 to 2</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/rollarcus_9_to_2"/>
        <published>2011-12-20T07:56:37+00:00</published>
        <updated>2013-08-18T15:39:29+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rollarcus" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;https://github.com/snoopdave/rollarcus&quot;&gt;
&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/b4a4fc0e-1e57-49cb-8c3d-893224f45694&quot; alt=&quot;rollarcus github logo&quot; align=&quot;right&quot;&gt;
&lt;/a&gt;

&lt;p&gt;I made some progress in Rollarcus over the past couple of weekends, but not a lot. This makes me wonder how I ever found the &amp;quot;nights and weekends&amp;quot; to get Roller started in the first place, but that&amp;#39;s a different topic.&lt;/p&gt;

&lt;p&gt;What I&amp;#39;ve done so far in Rollarcus is to simplify things. While I was at Sun, we split Roller up into a number of parts: a weblogger part for blogging, a planet part for RSS/Atom aggregation, a core part for things common to both. After Sun, I worked to move Roller to Maven and further split things up into a total of 9 Maven modules including an assembly for building the release. Now, I think that all these modules are unnecessary -- we never shipped a Roller-Planet application and nobody wants to use parts of Roller -- and even if they did, the modules did not really help.&lt;/p&gt;

&lt;p&gt;Here&amp;#39;s the before view: &lt;a href=&quot;https://github.com/apache/roller&quot;&gt;apache/roller&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here&amp;#39;s the after view: &lt;a href=&quot;https://github.com/snoopdave/rollarcus&quot;&gt;snoopdave/rollarcus&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, in Rollerarcus, I&amp;#39;ve merged all the modules. Except for one &amp;quot;test utilities&amp;quot; module, all Java code, JSPs and other code is now in one module and much easier to deal with. Next, I&amp;#39;m going to attack the (what I consider to be) unnecessary dependencies and drastically reduce the number of jars in WEB-INF.&lt;/p&gt;

&lt;p style=&quot;color:red;&quot;&gt;&lt;b&gt;UPDATE&lt;/b&gt;: The most significant of the changes that I made in Rollarcus have been applied by to Apache Roller and today (August 18, 2013) I removed the Rollarcus repository from Github.&lt;/p&gt; </content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/fork_it_all</id>
        <title type="html">Fork it all</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/fork_it_all"/>
        <published>2011-12-03T11:08:29+00:00</published>
        <updated>2013-08-18T15:39:16+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rollarcus" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;I just forked Roller on Github.&lt;/p&gt;

&lt;p&gt;The new project is called &lt;a href=&quot;https://github.com/snoopdave/rollarcus&quot;&gt;Rollarcus&lt;/a&gt; and is mostly just an experiment and, I hope, a learning experience. I&amp;#39;ve got some ideas about stripping Roller down to it&amp;#39;s core and making it more fun and easy to develop and deploy. We&amp;#39;ll see how far I get.&lt;/p&gt;

&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/f131bd82-22b3-41fa-967f-a87450aff1f7&quot; alt=&quot;arcus rolling cloud&quot;&gt;&lt;br&gt;
&lt;p&gt;In case you don&amp;#39;t already know, an &lt;a href=&quot;http://en.wikipedia.org/wiki/Arcus_cloud&quot;&gt;arcus&lt;/a&gt; cloud is a low, horizontal cloud formation.&lt;/p&gt;


&lt;p style=&quot;color:red;&quot;&gt;&lt;b&gt;UPDATE&lt;/b&gt;: The most significant of the changes that I made in Rollarcus have been applied by to Apache Roller and today (August 18, 2013) I removed the Rollarcus repository from Github.&lt;/p&gt; </content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/upgraded_to_roller_5_1</id>
        <title type="html">Upgraded to Roller 5.1-dev</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/upgraded_to_roller_5_1"/>
        <published>2011-11-26T14:19:28+00:00</published>
        <updated>2012-02-29T05:37:12+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="mobile" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;I just upgraded this site to Roller 5.1-dev, Subversion rev 1175172. This unreleased version of Roller includes new mobile theming capability (mentioned in my &lt;a href=&quot;http://rollerweblogger.org/roller/entry/roller_and_gsoc_2011&quot;&gt;previous post&lt;/a&gt;), allowing a theme to define both a standard and a &amp;quot;mobile&amp;quot; version of each weblog page. I haven&amp;#39;t added mobile pages for my blog yet, but that is what I plan to do next.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/wip_resource_preview</id>
        <title type="html">WIP: Resource Preview</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/wip_resource_preview"/>
        <published>2011-06-03T09:00:35+00:00</published>
        <updated>2011-06-03T16:02:35+00:00</updated> 
        <category term="Web Development" label="Web Development" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="oslc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="resourcepreview" scheme="http://roller.apache.org/ns/tags/" />
        <category term="uipreview" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wip" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;&lt;i&gt;This is the fourth in my series of Web Integration Patterns. Check out the intro at this URL &lt;a href=&quot;http://rollerweblogger.org/roller/entry/web_integration_patterns&quot;&gt;http://rollerweblogger.org/roller/entry/web_integration_patterns&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Synopsis&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Enhance links shown in HTML pages so that users can hover, mouse-over, or use some other gesture, to view a preview of the resource at the other end of the link.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Motivations&lt;/b&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make it convenient for a user to get information about a link but without having to navigate to the link and without having to leave the current web page in the browser.&lt;/li&gt;
&lt;li&gt;Make applications appear to be part of one integrated whole by enabling them to delegate to each other&amp;#39;s user interfaces for preview display.&lt;/li&gt;
&lt;/ul&gt;</summary>
        <content type="html">&lt;p&gt;&lt;i&gt;This is the fourth in my series of Web Integration Patterns. Check out the intro at this URL &lt;a href=&quot;http://rollerweblogger.org/roller/entry/web_integration_patterns&quot;&gt;http://rollerweblogger.org/roller/entry/web_integration_patterns&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Synopsis&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Enhance links shown in HTML pages so that users can hover, mouse-over, or use some other gesture, to view a preview of the resource at the other end of the link.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Motivations&lt;/b&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make it convenient for a user to get information about a link but without having to navigate to the link and without having to leave the current web page in the browser.&lt;/li&gt;
&lt;li&gt;Make applications appear to be part of one integrated whole by enabling them to delegate to each other&amp;#39;s user interfaces for preview display.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;Complements&lt;/b&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://rollerweblogger.org/roller/entry/wip_links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Delegated Resource Creation &amp;amp; Selection&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://rollerweblogger.org/roller/entry/wip_common_navigation&quot;&gt;Common Navigation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This pattern allows users to view a preview of links that are displayed in a web page. This preview might be a simple tool-tip with plain-text, a more rich JavaScript-driven display with hyper-text and graphics, or it might be a thumbnail view of the page at the other end of the link.&lt;/p&gt;

&lt;p&gt;Resource Preview works well for web applications that use the &lt;a href=&quot;http://rollerweblogger.org/roller/entry/wip_links&quot;&gt;Links&lt;/a&gt; pattern for integration and use links to establish relationships between resources. If a user is looking at a Bug Report, for example, they might see a list of links to associated resources like attachments to the bug, test cases impacted by the bug, etc. The user can hover over links and see a preview with key information for each link, without leaving the current web page that they are on. Below are three different approaches to applying the Resource Preview pattern in web applications.&lt;/p&gt;

&lt;h3&gt;Approach #1: Preview Site offers previews to other applications&lt;/h3&gt;

&lt;p&gt;With this approach, there is a special preview site that crawls a set of web sites and creates Resource Previews of the web pages of those sites. Then, web sites that wish to display previews on links use some special JavaScript magic to display those previews. An example of this preview site approach is &lt;a href=&quot;http://www.snap.com/&quot;&gt;Snap.com&lt;/a&gt;&#146;s &lt;a href=&quot;http://www.snap.com/snapshots.php&quot;&gt;Snap-Shots&lt;/a&gt; service. Anybody with a web site can sign up for the service, get some special HTML code that can be added to their site to display a graphical and thumbnail-style preview whenever a user hovers over a link.&lt;/p&gt; 

&lt;p&gt;Here&#146;s an example of a Snap.com preview on the company&#146;s blog:&lt;/p&gt;

&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/d5be1c22-5263-4286-a025-6fc2aa7f4c44&quot; alt=&quot;Snap.com preview&quot;&gt;

&lt;p&gt;The advantages of the preview site approach are participating sites don&#146;t have to do anything except for adding a small bit of JavaScript code to enable previews. The disadvantage is that the automatically generated previews often can&#146;t offer more than a page title, thumbnail image and perhaps a short excerpt from the page being previewed. Also, it&#146;s interesting to note that  there was a &lt;a href=&quot;http://thenextweb.com/2008/01/26/snapcom-to-critics-you-wanna-step-outside/&quot;&gt;backlash&lt;/a&gt; against Snap-Shots and some people thought they were distracting and gimmicky. Regardless of that criticism, this approach to Resource Previews is not very interesting from a Web Integration Patterns point of view because the focus is making one site more useful and interactive, and not integrating with others.&lt;/p&gt;

&lt;h3&gt;Approach #2: Application creates and displays previews as needed&lt;/h3&gt;

&lt;p&gt;With this approach, an application that needs to provide preview creates the previews that it needs and take case of displaying them. The best known examples of this approach are probably the preview features built into Microsoft&#146;s Bing and Google&#146;s search engine. This approach is also not very interesting as a WIP because its all about making one site more useful, not integrating with others.&lt;/p&gt;

&lt;p&gt;Here&#146;s an example of a Resource Preview in Microsoft Bing:&lt;/p&gt;

&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/46c0d83d-597e-4dad-8eaa-1ada5e933795&quot; alt=&quot;Bing preview&quot;&gt;

&lt;h3&gt;Approach #3: Applications offer previews of their own resources&lt;/h3&gt;

&lt;p&gt;This approach is to enable web applications provide previews of their own resources and make them available via a simple protocol. The best example of this approach is &lt;a href=&quot;http://open-services.net/bin/view/Main/OslcCoreUiPreview&quot;&gt;OSLC UI Preview&lt;/a&gt;, which is part of the &lt;a href=&quot;http://open-services.net&quot;&gt;OSLC specifications&lt;/a&gt;. The OSLC specs are designed to enable integration between ALM tools, but can be applied to integrating web applications of almost any stripe. Applications that implement OSLC UI Preview provide a UI Preview for each resource, one that provides a summary of the resource and links to large and small previews of the resource. &lt;/p&gt;

&lt;p&gt;Here&#146;s an example of an &lt;a href=&quot;http://fusionforge.org/plugins/mediawiki/wiki/fusionforge/index.php/OslcCompactPreviewTooltips&quot;&gt;OSLC UI Preview from FusionForge&lt;/a&gt;, an open source ALM suite:&lt;/p&gt;

&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/ad5008ea-2010-4873-9140-fdad5d87c2fc&quot; alt=&quot;FusionForge preview&quot;&gt;

&lt;p&gt;Here&#146;s an example of a Resource Preview from &lt;a href=&quot;https://jazz.net/projects/rational-team-concert/&quot;&gt;IBM Rational Team Concert&lt;/a&gt;, which also implements the OSLC UI Preview spec:&lt;/p&gt;

&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/95919538-b750-4ba8-b96f-272f5b020d46&quot; alt=&quot;RTC preview&quot;&gt;

&lt;p&gt;There are several advantages to this approach. Preview-providing applications have complete control over the content and appearance of previews for their resources. Preview-consuming applications don&#146;t have to create and format them, they just display what comes back from the provider. No special preview site is needed to enable previews. Another advantage to this approach to Resource Previews is the OSLC UI Preview specification, which defines an open and standard way to provide and consume previews.&lt;/p&gt;

&lt;h3&gt;Wrapping up&lt;/h3&gt;

&lt;p&gt;I&amp;#39;ve explained what I call the Resource Pattern and three different ways that I&amp;#39;ve seen it used. Resource Preview is a good way to add value to the &lt;a href=&quot;http://rollerweblogger.org/roller/entry/wip_links&quot;&gt;Links&lt;/a&gt; pattern and to make links even more useful. The best way to implement this pattern is to ask all web applications that want to integrate to offer Resource Previews via a standard protocol such as OSLC UI Preview, and to display them whenever a user hovers over a link.&lt;/p&gt;
</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/oslc_core_spec_final</id>
        <title type="html">OSLC Core v2 specification now FINAL</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/oslc_core_spec_final"/>
        <published>2011-06-01T14:38:13+00:00</published>
        <updated>2011-06-01T21:38:47+00:00</updated> 
        <category term="IBM" label="IBM" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="linkeddata" scheme="http://roller.apache.org/ns/tags/" />
        <category term="oslc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rest" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wip" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/04fe2c5b-9719-4e13-9221-70a0645b48e0&quot; align=&quot;right&quot; hspace=&quot;5&quot;&gt;
I&amp;#39;ve been working on the OSLC Core specification for about 1.5 years now as workgroup lead, and &lt;a href=&quot;http://open-services.net&quot;&gt;OSLC&lt;/a&gt; fits squarely under the &amp;quot;open web technologies&amp;quot; and &lt;a href=&quot;http://rollerweblogger.org/roller/entry/web_integration_patterns&quot;&gt;Web Integration Patterns&lt;/a&gt; topics of this blog, so I&amp;#39;m blogging this happy news. &lt;/p&gt;

&lt;p&gt;Here&amp;#39;s the announcement From the OSLC Core Workgroup mailing list:&lt;/p&gt;

&lt;pre&gt;
From: Dave Johnson
To: oslc-core (a) open-services.net, community (a) open-services.net
Subject: OSLC Core v2 specification now FINAL

Today [1], I&amp;#39;m very happy to announce that the OSLC Core v2
specification is FINAL.

The OSLC Core v2 specification [2] defines a set of REST and Linked
Data-based patterns, resources and protocols for integration of application 
and product lifecycle resources (ALM and PLM). It&amp;#39;s designed to be the
foundation for all other OSLC domain specifications and there are now
three final OSLC specifications that are based on the Core, those
being the OSLC Change Management (CM) [3], OSLC Quality Management
(QM) [4] and OSLC Requirements Management (RM) [5] specs.

I&amp;#39;d like to thank all of the members of the OSLC Core Workgroup and
community for their hard work, critical thinking and ability to work
together in such a productive and pleasant way. Also, special thanks
to those OSLC domain workgroups who rebased their work on the Core and
development teams that provided excellent feedback along the way.

Thanks,
- Dave

--
David M. Johnson
OSLC Core Workgroup Lead
IBM Rational Software


[1] Move to final was proposed last week, along with a small set of
changes which have since been applied to the specification. 
[2] &lt;a href=&quot;http://open-services.net/bin/view/Main/OslcCoreSpecification&quot;&gt;OslcCoreSpecification&lt;/a&gt;
[3] &lt;a href=&quot;http://open-services.net/bin/view/Main/CmSpecificationV2&quot;&gt;CmSpecificationV2&lt;/a&gt;
[4] &lt;a href=&quot;http://open-services.net/bin/view/Main/QmSpecificationV2&quot;&gt;QmSpecificationV2&lt;/a&gt;
[5] &lt;a href=&quot;http://open-services.net/bin/view/Main/RmSpecificationV2&quot;&gt;RmSpecificationV2&lt;/a&gt;
&lt;/pre&gt;

&lt;p&gt;I really do have another &lt;a href=&quot;http://rollerweblogger.org/roller/entry/web_integration_patterns&quot;&gt;Web Integration Patterns&lt;/a&gt; post on the way shortly, so stay tuned.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/apache_roller_5_0_released</id>
        <title type="html">Apache Roller 5.0 released</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/apache_roller_5_0_released"/>
        <published>2011-05-25T14:06:00+00:00</published>
        <updated>2011-05-25T21:10:31+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="apacheroller" scheme="http://roller.apache.org/ns/tags/" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="opensource" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;&lt;i&gt;(cross-posted from the Roller project blog)&lt;/i&gt;
&lt;/p&gt;&lt;p&gt;
&lt;p&gt;Here&amp;#39;s some more happy Roller news. Apache Roller 5.0 has been released! 
&lt;/p&gt;
&lt;p&gt;http://rollerweblogger.org/project/mediaresource/3cdaff7b-2745-4dac-89c9-151a3a1ccf26&amp;#39; 
align=&amp;#39;right&amp;#39; style=&amp;#39;padding:1em&amp;#39; /&amp;gt;
&lt;/p&gt;
&lt;p&gt;The major new feature in Roller 5.0 is Media Blogging, a set of enhancements to Roller&amp;#39;s file upload and management capabilities. Also included in 5.0 are simple multi-site support, OpenID and ~OAuth support for Roller&amp;#39;s AtomPub interface. All major dependencies have been updated and Roller now uses Maven for build and dependency management. You can find a summary of &lt;a class=&quot;external&quot; href=&quot;http://cwiki.apache.org/confluence/display/ROLLER/What%27s+new+in+Roller+5.0&quot;&gt;Roller 5.0&amp;#39;s new features&lt;/a&gt; on the Roller wiki.
&lt;/p&gt;
&lt;p&gt;The road to Roller 5.0 has been a long one and if you are interested the history, you might want to check Dave Johnson&amp;#39;s &lt;a class=&quot;external&quot; href=&quot;http://www.slideshare.net/snoopdave/whats-new-in-roller5&quot;&gt;What&amp;#39;s New in Roller 5.0&lt;/a&gt; presentation from ApacheCon US 2009. Roller 5.0 includes contributions from contributors from Google Summer of Code, San Jose State Univ. and the usual case of Roller committers. Thanks to all who contributed to Roller 5.0 over the years.
&lt;/p&gt;
&lt;p&gt;To download Apache Roller 5.0 and documentation, visit the &lt;a class=&quot;external&quot; href=&quot;http://roller.apache.org/downloads.html&quot;&gt;Apache Roller download page&lt;/a&gt; at the Apache Software Foundation&amp;#39;s website.
&lt;/p&gt;&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/welcome_new_roller_committer_shelan</id>
        <title type="html">Welcome new Apache Roller committer Shelan Perera</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/welcome_new_roller_committer_shelan"/>
        <published>2011-05-23T17:53:33+00:00</published>
        <updated>2011-05-25T21:34:35+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gsoc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="mobile" scheme="http://roller.apache.org/ns/tags/" />
        <category term="roller" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;&lt;i&gt;(cross-posted from the Roller project blog)&lt;/i&gt;
&lt;/p&gt;&lt;p&gt;
&lt;p&gt;Here&amp;#39;s some happy news. A new committer has joined the Apache Roller project. Shelan Perera has been helping out on the mailing lists, submitting fixes and recently won a Google Summer of Code (GSOC) project to add mobile blogging features to Roller. He was nominated for committer-ship and voted in on May 5, 2011.
&lt;/p&gt;
&lt;p&gt;Shelan&amp;#39;s GSOC project is to add mobile theming capabilities to Roller. You can find the &lt;a class=&quot;external&quot; href=&quot;http://socghop.appspot.com/gsoc/proposal/review/google/gsoc2011/shelan/1&quot;&gt;Mobile Theming for Roller&lt;/a&gt; proposal on the GSOC website. Shelan is seeking feedback on requirements and design for the project, and keeping the community in the loop by running a blog to journal his progress: &lt;a class=&quot;external&quot; href=&quot;http://rollermobile.blogspot.com&quot;&gt;Apache Roller Mobile Platform&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;Welcome Shelan!&lt;/p&gt;&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/inside_out_half_marathon_2011</id>
        <title type="html">Inside Out Half-Marathon 2011</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/inside_out_half_marathon_2011"/>
        <published>2011-05-22T16:47:27+00:00</published>
        <updated>2011-05-23T15:24:03+00:00</updated> 
        <category term="General" label="General" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="running" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/382ab2bf-54c2-48ee-afc7-fa908871c5e2&quot; align=&quot;right&quot; alt=&quot;race medals&quot; title=&quot;race medals&quot;&gt;
&lt;p&gt;I&amp;#39;ll be resuming my Web Integration Patterns blog series this week, now that I have some &amp;quot;free&amp;quot; time again. It&amp;#39;s been a busy Spring at work and at home, especially during April and May. My early mornings, evenings and weekends were consumed by half-marathon training, (and the Apache Roller 5.0 release, more about that later).&lt;/p&gt;

&lt;p&gt;As for the &lt;a href=&quot;http://www.ncroadrunners.org/IOClassic/&quot;&gt;half-marathon&lt;/a&gt;, it went very well. I really enjoyed training and running with my oldest son. The race was today and we&amp;#39;re both pretty happy with our &lt;a href=&quot;http://results.active.com/pages/page.jsp?eventID=1929764&amp;pubID=3&quot;&gt;results&lt;/a&gt;, which you can see below.&lt;/p&gt; 

&lt;pre&gt;
13th Annual Inside-Out Sports Classic - Half-Marathon

Place Bib  Name                    S Ag City             St Chiptim Guntime Pace  
===== ==== ======================= = == ================ == ======= ======= ===== 
  247  308 ALEX JOHNSON            M 14 RALEIGH          NC 1:59:10 1:59:18  9:06
  154  309 DAVE JOHNSON            M 47 RALEIGH          NC 1:50:34 1:50:43  8:27 
&lt;/pre&gt;

&lt;p&gt;The race course is wonderful and runs through &lt;a href=&quot;http://www.ncparks.gov/Visit/parks/wium/main.php&quot;&gt;Umstead park&lt;/a&gt; on the small-grain gravel bridle trails there. Here&amp;#39;s the &lt;a href=&quot;http://www.dailymile.com/routes/673251-running-route-in-cary-nc&quot;&gt;route map&lt;/a&gt; I made on dailymile.com (check out the Elevation Profile, it&amp;#39;s a hilly one).&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/wip_embedded_properties_in_html</id>
        <title type="html">WIP: Embedded Properties in HTML</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/wip_embedded_properties_in_html"/>
        <published>2011-04-07T21:57:52+00:00</published>
        <updated>2011-06-03T00:18:07+00:00</updated> 
        <category term="Web Development" label="Web Development" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="html" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rdf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rdfa" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wip" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;&lt;i&gt;This is the third in my series of Web Integration Patterns. Check out the intro at this URL &lt;a href=&quot;http://rollerweblogger.org/roller/entry/web_integration_patterns&quot;&gt;http://rollerweblogger.org/roller/entry/web_integration_patterns&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Synopsis&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Enable easier integration and better search across integrated web applications and sites by using standard mechanisms (e.g. Microformats, RDFa) to embed property values in HTML pages.&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;&lt;i&gt;This is the third in my series of Web Integration Patterns. Check out the intro at this URL &lt;a href=&quot;http://rollerweblogger.org/roller/entry/web_integration_patterns&quot;&gt;http://rollerweblogger.org/roller/entry/web_integration_patterns&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Synopsis&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Enable easier integration and better search across integrated web applications and sites by using standard mechanisms (e.g. Microformats, RDFa) to embed property values in HTML pages.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Motivations&lt;/b&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable integrated web applications to read, parse and make use of each others data&lt;/li&gt;
&lt;li&gt;Enable better search across integrated web applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;Related Patterns&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://rollerweblogger.org/roller/entry/wip_links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Web APIs&lt;/li&gt;
&lt;li&gt;Linked Data + REST&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this pattern, you define different types of resources or &#147;objects,&amp;quot; and the properties may be associated with each, or you adopt an existing vocabulary. You define a way to embed type information and properties values into HTML, by embedding name and value pairs in a way invisible to a user or by marking up strings of visible text as property values, or you adopt an existing technique.&lt;/p&gt;

&lt;p&gt;For example, a cooking web site could share recipe data using this pattern by presenting each recipe with embedded property values to make it easy for other web applications, mash-ups and search engines to parse out the different parts of the recipe, title, ingredients list, list of steps, etc. This is a real example, by the way, &lt;a href=&quot;http://www.google.com/support/webmasters/bin/answer.py?answer=173379&quot;&gt;Google indexes recipe data in HTML pages&lt;/a&gt; marked up in either Microformat-style or RDFa.&lt;/p&gt;

&lt;p&gt;If you present each web page as a resource with a type, or multiple types, and embedded property values then you don&#146;t need to define and provide a special &#147;REST API&#148; to allow other web applications to access your data. &lt;/p&gt;

&lt;p&gt;This pattern can enable more powerful search capabilities across integrated web application because search engine&#146;s can be aware of and provide special indexing for those different types of resources and properties.&lt;/p&gt;

&lt;p&gt;There are at least three different standard ways to embed data in HTML: Microformats, HTML Microdata and RDFa, each of which I&#146;ll explain below.&lt;/p&gt;

&lt;h4&gt;Microformats&lt;/h4&gt;

&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/237ec029-cb39-4f8f-988e-806fb6abf912&quot; alt=&quot;Microformats logo&quot; align=&quot;right&quot; width=&quot;180&quot; height=&quot;50&quot;&gt;

&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Microformat&quot;&gt;According to Wikipedia&lt;/a&gt; &#147;Microformats emerged as part of a grassroots movement to make recognizable data items (such as events, contact details or geographical locations) capable of automated processing by software, as well as directly readable by end-users.&#148; A community grew around Microformats and this community has worked to define Microformats for a variety of use cases. The &lt;a href=&quot;http://microformats.org&quot;&gt;microformats.org&lt;/a&gt; web site lists nine microformats, including &lt;a href=&quot;http://microformats.org/wiki/hcard&quot;&gt;hCard&lt;/a&gt; for sharing contact information, &lt;a href=&quot;http://microformats.org/wiki/hcalendar&quot;&gt;hCalendar&lt;/a&gt; for sharing events and hReview for sharing movie and book reviews.&lt;/p&gt;

&lt;p&gt;The basic idea of Microformats is to use existing HTML element attributes, specifically rel and class, to convey types of things and properties of those things. Here&#146;s an example from Wikipedia: to represent information about a geographic location in HTML, the &lt;a href=&quot;http://microformats.org/wiki/geo&quot;&gt;Geo Microformat&lt;/a&gt; uses the syntax below:
&lt;/p&gt;

&lt;pre&gt;

   The birds roosted at
     &amp;lt;span class=&amp;quot;geo&amp;quot;&amp;gt;
     &amp;lt;span class=&amp;quot;latitude&amp;quot;&amp;gt;52.48&amp;lt;/span&amp;gt;,
     &amp;lt;span class=&amp;quot;longitude&amp;quot;&amp;gt;-1.89&amp;lt;/span&amp;gt;
   &amp;lt;/span&amp;gt;&lt;/pre&gt;

&lt;p&gt;The outer-most span&#146;s class element indicates the type &amp;quot;geo&amp;quot; and the inner spans carry the &amp;quot;latitude&amp;quot; and &amp;quot;longitude&amp;quot; property values.&lt;/p&gt;

&lt;p&gt;If you want to take advantage of Microformats in web application integration, then you pick one of the existing formats or you invent a new one, ideally by working with the Microformats community to do so. &lt;/p&gt;

&lt;p&gt;Another approach for implementing Embedded Properties in HTML is HTML itself.&lt;/p&gt;

&lt;h4&gt;HTML(5) Microdata&lt;/h4&gt;

&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/a5dd6440-5fcd-4b48-9d56-fe71dd0862d5&quot; alt=&quot;HTML5 logo&quot; align=&quot;right&quot; width=&quot;100&quot; height=&quot;100&quot;&gt;

&lt;p&gt;&lt;a href=&quot;http://www.w3.org/TR/2011/WD-microdata-20110405/&quot;&gt;HTML Microdata&lt;/a&gt; is a W3C working draft, a specification that defines ways to embed property values in HTML. As Mark Pilgrim &lt;a href=&quot;http://diveintohtml5.org/extensibility.html#what-is-microdata&quot;&gt;explains in Dive Into HTML5&lt;/a&gt;, HTML Microdata &#147;annotates the DOM with scoped name/value pairs from custom vocabularies.&#148; This is very similar to what Microformats do, but instead of &#147;overloading&#148; the class attribute, HTML Microdata adds some new HTML attributes to enable embedded property values.&lt;/p&gt;

&lt;p&gt;HTML Microdata enables you to mark-up an HTML element as an item that contains properties. You do this via the &lt;b&gt;itemscope&lt;/b&gt; attribute, you indicate the item&#146;s type via the &lt;b&gt;itemtype&lt;/b&gt; attribute and each property is indicated by the &lt;b&gt;itemprop&lt;/b&gt; attribute. Here&#146;s an example, also from Pilgrim&#146;s book:&lt;/p&gt;

&lt;pre&gt;

   &amp;lt;TABLE itemscope itemtype=&amp;quot;http://data-vocabulary.org/Person&amp;quot;&amp;gt;
     &amp;lt;TR&amp;gt;&amp;lt;TD&amp;gt;Name&amp;lt;TD&amp;gt;Mark Pilgrim
     &amp;lt;TR&amp;gt;&amp;lt;TD&amp;gt;Link&amp;lt;TD&amp;gt;
       &amp;lt;span itemprop=&amp;quot;url&amp;quot;&amp;gt;
       &amp;lt;A href=# onclick=goExternalLink()&amp;gt;http://diveintomark.org/&amp;lt;/A&amp;gt;
       &amp;lt;/span&amp;gt;
   &amp;lt;/TABLE&amp;gt;

&lt;/pre&gt;

&lt;p&gt;The table element defines the scope of the item and the type of the item is a URL &lt;a href=&quot;http://www.data-vocabulary.org/Person/&quot;&gt;http://data-vocabulary.org/Person&lt;/a&gt; which indicates that the item represents a person. The enclosed span element carries the &#147;url&#148; property of the person.&lt;/p&gt;

&lt;p&gt;It&#146;s good to have a standard way to encode types, scope and property values in HTML, but you also need standard vocabularies of types and properties to make this approach successful. There are some HTML Microdata vocabularies defined at data-vocabulary.org and HTML Microdata can also be used with RDF, opening up a huge number of vocabularies.&lt;/p&gt;

&lt;h4&gt;RDFa&lt;/h4&gt;

&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/26e3fa3f-a271-4d98-a6a8-356b02610c4d&quot; alt=&quot;RDFa Logo&quot; align=&quot;right&quot;&gt;

&lt;p&gt;&lt;a href=&quot;http://www.w3.org/2010/02/rdfa/&quot;&gt;RDFa&lt;/a&gt; is a W3C recommendation, a specification that defines ways to embed RDF data in HTML and XHTML. Like HTML Microdata, RDFa adds new attributes to HTML to enable this. Let&#146;s look at an example from the &lt;a href=&quot;http://en.wikipedia.org/wiki/RDFa&quot;&gt;Wikipedia page on RDFa&lt;/a&gt;, which uses two of these attributes &lt;b&gt;about&lt;/b&gt; and &lt;b&gt;property&lt;/b&gt;:&lt;/p&gt;

&lt;pre&gt;
 
   &amp;lt;div xmlns:dc=&amp;quot;http://purl.org/dc/elements/1.1/&amp;quot;
     about=&amp;quot;http://www.example.com/books/wikinomics&amp;quot;&amp;gt;
     &amp;lt;span property=&amp;quot;dc:title&amp;quot;&amp;gt;Wikinomics&amp;lt;/span&amp;gt;
     &amp;lt;span property=&amp;quot;dc:creator&amp;quot;&amp;gt;Don Tapscott&amp;lt;/span&amp;gt;
     &amp;lt;span property=&amp;quot;dc:date&amp;quot;&amp;gt;2006-10-01&amp;lt;/span&amp;gt;
   &amp;lt;/div&amp;gt;

&lt;/pre&gt;

&lt;p&gt;The above example embeds some property values about the book Wikinomics, which is identified by URL http://www.example.com/books/wikinomics. The example provides a title, creator and date values about that resource, and it doesn&#146;t say what type of resource exists at the URL, but it could.&lt;/p&gt;

&lt;p&gt;The advantage of the RDFa approach is that it ties in with the growing RDF / Linked Data movement, and the huge number of vocabularies from almost every field of endeavor. RDFa has some momentum and has been adopted by Facebook in its &lt;a href=&quot;http://ogp.me/&quot;&gt;OpenGraph Protocol&lt;/a&gt; and &lt;a href=&quot;http://www.readwriteweb.com/archives/w3c_pleased_with_semantic_web_adoption.php&quot;&gt;Best Buy&lt;/a&gt; for exposing catalog data in standard ways. However, HTML Microdata can also be used with RDF, so RDFa is not the only way to go if you favor Linked Data.&lt;/p&gt;

&lt;h4&gt;Wrapping up&lt;/h4&gt;

&lt;p&gt;We&amp;#39;ve talked about three different ways to implement Embedded Properties in HTML, so which one do you choose? It&amp;#39;s not to me whether one of these techniques will dominate. Google is hedging its bet, so to speak, by indexing all three types of data. If you don&amp;#39;t already have a favorite, one way to choose is to look at what others in your community, company or &amp;quot;industry vertical&amp;quot; are doing. The &lt;a href=&quot;http://en.wikipedia.org/wiki/Network_effect&quot;&gt;network effect&lt;/a&gt; applies here, so if one technique is already favored amongst web application or sites in your space, then go with that.&lt;/p&gt;

&lt;p&gt;Next up: Resource Preview&lt;/p&gt;
</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/wip_common_navigation</id>
        <title type="html">WIP: Common Navigation</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/wip_common_navigation"/>
        <published>2011-03-27T10:08:44+00:00</published>
        <updated>2011-06-03T00:18:02+00:00</updated> 
        <category term="Web Development" label="Web Development" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jazz" scheme="http://roller.apache.org/ns/tags/" />
        <category term="lotusconnections" scheme="http://roller.apache.org/ns/tags/" />
        <category term="patterns" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ux" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wip" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p style=&quot;font-style:italic;&quot;&gt;
This is the second in my series of Web Integration Patterns. Check out the intro at this URL &lt;a href=&quot;http://rollerweblogger.org/roller/entry/web_integration_patterns&quot;&gt;http://rollerweblogger.org/roller/entry/web_integration_patterns&lt;/a&gt;&lt;/p&gt;

&lt;p style=&quot;font-weight:bold;&quot;&gt;
Synopsis&lt;/p&gt;

&lt;p&gt;Make separate web sites and applications appear to be one by using common user interface elements for navigation.&lt;/p&gt;
</summary>
        <content type="html">&lt;p style=&quot;font-style:italic;&quot;&gt;
This is the second in my series of Web Integration Patterns. Check out the intro at this URL &lt;a href=&quot;http://rollerweblogger.org/roller/entry/web_integration_patterns&quot;&gt;http://rollerweblogger.org/roller/entry/web_integration_patterns&lt;/a&gt;&lt;/p&gt;

&lt;p style=&quot;font-weight:bold;&quot;&gt;Synopsis&lt;/p&gt;

&lt;p&gt;Make separate web sites and applications appear to be one by using common user interface elements for navigation.&lt;/p&gt;

&lt;p style=&quot;font-weight:bold;&quot;&gt;
Motivations&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provide easy navigation between integrated web sites &amp;amp; applications.&lt;/li&gt;
&lt;li&gt;Make separate web sites appear to be one and parts of the same overall user interface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p style=&quot;font-weight:bold;&quot;&gt;
Related patterns&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://rollerweblogger.org/roller/entry/wip_links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This pattern is an extension of the Links pattern. The idea is to use links combined with common user interface (UI) elements, as a way to provide navigation between integrated sites and to make the separate sites appear to be parts of a whole application. This pattern is usually implemented via a banner with links, a tabs or some other type of menu component.&lt;/p&gt;

&lt;p&gt;To make this work, somebody has to create the common navigation, give it an attractive design, decide which web sites or applications are included in the navigation. Consequently, this pattern works well for a set of web sites owned by the same organization, or a suite of packaged web applications.&lt;/p&gt;

&lt;h3&gt;Pros and Cons&lt;/h3&gt;

&lt;p&gt;The advantages of Common Navigation are that it works, it does make separate web sites seem to be part of one integrated whole and it&amp;#39;s relatively easy to implement. One disadvantage of this approach is that the Common Navigation elements can either conflict with, in a visual sense, or distract from the web sites themselves. But if you&amp;#39;re selling a suite of web applications, you&amp;#39;ve got control of whole design and you can solve this problem.&lt;/p&gt;

&lt;h3&gt;Examples&lt;/h3&gt;

&lt;p&gt;Here are some examples of Common Navigation that I see almost everyday. The first is Google.&lt;/p&gt;

&lt;p style=&quot;font-weight:bold;&quot;&gt;Common Navigation in Google web applications&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://gmail.com&quot;&gt;Google Mail&lt;/a&gt;, Calendar and other Google apps all share a Common Navigation bar across the top of the page. Google decides which apps appear in the menu, and the tech blogs whine whenever an item is moved or removed from the line-up. This is  a pretty shallow integration: just links to applications and no more.&lt;/p&gt;

&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/50121a6f-4e8a-43a6-a13a-b01e11a1ca6c&quot;&gt;

&lt;p&gt;Now, let&amp;#39;s see a deeper example.&lt;/p&gt;

&lt;p style=&quot;font-weight:bold;&quot;&gt;Common Navigation in IBM Lotus Connections&lt;/p&gt;

&lt;p&gt;IBM &lt;a href=&quot;http://www.ibm.com/software/lotus/products/connections/&quot;&gt;Lotus Connections&lt;/a&gt; is a suite of social software applications including social networking, blogs, wiki, forums, file sharing and etc. As you can see below, Common Navigation is used to provide links, not just to applications, but into specific parts of applications. For example, the Latest Entries page in the Blogs app, and the Wikis that I own vs. Public Wikis.&lt;/p&gt;

&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/6284aed1-5625-4ae3-b387-b5e7ad5ba47d&quot;&gt;

&lt;p&gt;Next, another suite example.&lt;/p&gt;

&lt;p style=&quot;font-weight:bold;&quot;&gt;Common Navigation in IBM Rational Team Concert&lt;/p&gt;

&lt;p&gt;IBM Rational&amp;#39;s Jazz-based products use Common Navigation, but with a project-orientation, showing a user&amp;#39;s project&amp;#39;s within each application. You can see this below in &lt;a href=&quot;http://jazz.net/projects/rational-team-concert/&quot;&gt;Rational Team Concert&lt;/a&gt;. A development project spans different applications and may have requirements managed by one web application, defects tracked by another, test cases managed by a third and so on. Each user sees the right menu for their projects.&lt;/p&gt;

&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/79dbc845-bfab-42a7-80b5-72f449394072&quot;&gt;

&lt;p&gt;Next, an example that&amp;#39;s not a suite of web applications.&lt;/p&gt;

&lt;p style=&quot;font-weight:bold;&quot;&gt;Common Navigation in StumleUpon&lt;/p&gt;

&lt;p&gt;Another example is &lt;a href=&quot;http://www.stumbleupon.com/&quot;&gt;StumbleUpon&lt;/a&gt;. When you use StumbleUpon, you see the banner at the top of every page. You press the Stumble! button and a you see a randomly selected web page from anywhere on the web, or from some specific category of web site, and you still see the StumbleUpon banner. The StumbleUpon banner makes the whole web seem like one big site, deigned for &amp;quot;stumbling&amp;quot; around and sharing the things you find with friends.&lt;/p&gt;

&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/8a8b1e37-75e9-44fe-a1d4-494bdd2298e1&quot;&gt;

&lt;h3&gt;Wrapping up&lt;/h3&gt;

&lt;p&gt;I wasn&amp;#39;t sure that Common Navigation really deserved its own pattern, as it&amp;#39;s really just a simple and obvious application of the Links pattern, but I think this works. As always, feedback is welcome. What did I get wrong? What did I leave out?&lt;/p&gt;

&lt;p&gt;Next up: Web Annotations.&lt;/p&gt;
</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/web_integration_patterns</id>
        <title type="html">Web Integration Patterns</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/web_integration_patterns"/>
        <published>2011-03-15T09:30:40+00:00</published>
        <updated>2012-10-08T18:55:52+00:00</updated> 
        <category term="Web Development" label="Web Development" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="patterns" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wip" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;In my &lt;a href=&quot;http://rollerweblogger.org/roller/entry/more_than_bloggy&quot;&gt;previous post&lt;/a&gt;, I promised to write a blog series on Web Integration Patterns. This post explains the concept and a bit about how I plan to write about it.&lt;/p&gt;

&lt;p&gt;What I&#146;m calling Web Integration Patterns are techniques for integrating software systems, web applications and web sites using the common technologies of the web. These patterns build on HTTP, HTML, JavaScript and sometimes JSON, RDF and XML to provide ways to integrate software systems and include both programmatic approaches and user interface integrations.&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;In my &lt;a href=&quot;http://rollerweblogger.org/roller/entry/more_than_bloggy&quot;&gt;previous post&lt;/a&gt;, I promised to write a blog series on Web Integration Patterns. This post explains the concept and a bit about how I plan to write about it.&lt;/p&gt;

&lt;p&gt;What I&#146;m calling Web Integration Patterns are techniques for integrating software systems, web applications and web sites using the common technologies of the web. These patterns build on HTTP, HTML, JavaScript and sometimes JSON, RDF and XML to provide ways to integrate software systems and include both programmatic approaches and user interface integrations.&lt;/p&gt;

&lt;h4&gt;Not the same as Enterprise Integration Patterns&lt;/h4&gt;

&lt;p&gt;These patterns are different from &lt;a href=&quot;http://www.eaipatterns.com/&quot;&gt;Enterprise Integration Patterns&lt;/a&gt; (from the book of the same title). Those enterprise patterns make the most sense inside an organization where shared-databases and specifically messaging middle-wares are part of the common infrastructure. Web Integration Patterns assume only the web as common infrastructure, or at least the best of them do, and that means they can work equally as well in a controlled enterprise Intranet as they do on the big wild Internet. They can work well for a suite of web applications or a family of loosely related web sites.&lt;/p&gt;

&lt;h4&gt;Four categories of patterns covered&lt;/h4&gt;

&lt;p&gt;I plan to write about a dozen blog entries each covering one pattern, and I&#146;ll do at least one per week. I&#146;ll start with the basic patterns then introduce more advanced patterns. I&#146;ve organized the patterns into four groupings, listed below in the order that I will cover them:&lt;/p&gt;

(I&amp;#39;ll add links in below as I publish each pattern)

&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Basic Patterns&lt;/span&gt;: fundamental patterns which are relatively easy to implement, and, mostly, possible on a website made up of static HTML pages.
&lt;ul&gt;
   &lt;li&gt;#1 &lt;a href=&quot;http://rollerweblogger.org/roller/entry/wip_links&quot;&gt;Links&lt;/a&gt;: Use links as a way to integrate web sites &amp; applications via navigation and relationships between resources.&lt;/li&gt;
   &lt;li&gt;#2 &lt;a href=&quot;http://rollerweblogger.org/roller/entry/wip_common_navigation&quot;&gt;Common Navigation&lt;/a&gt;: Make separate web sites and applications appear to be one by using common user interface elements for navigation.&lt;/li&gt;
   &lt;li&gt;#3 &lt;a href=&quot;http://rollerweblogger.org/roller/entry/wip_embedded_properties_in_html&quot;&gt;Embedded Properties in HTML&lt;/a&gt;: Enable easier integration and better search across integrated web applications and sites by using standard mechanisms (e.g. Microformats, RDFa) to embed property values in HTML pages.
   &lt;li&gt;#4 &lt;a href=&quot;http://rollerweblogger.org/roller/entry/wip_resource_preview&quot;&gt;Resource Preview&lt;/a&gt;: Enhance links shown in HTML pages so that users can hover, mouse-over, or use some other gesture, to view a preview of the resource at the other end of the link.&lt;/li&gt;
   &lt;li&gt;#5 &lt;a href=&quot;http://rollerweblogger.org/roller/entry/wip_widgets_and_gadgets&quot;&gt;Widgets and Gadgets&lt;/a&gt;: Allow other web sites and applications to integrate your site into their web pages by providing an embeddable user interface, commonly known as a Gadget or Widget&lt;/li&gt;
    &lt;li&gt;#6 &lt;a href=&quot;http://rollerweblogger.org/roller/entry/wip_feed_based_integration&quot;&gt;Feed-based Integration&lt;/a&gt; integrating web sites and applications by using standard feed formats, e.g. RSS and Atom, to convey timely information, updates, status messages, events and other information&lt;/li&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Advanced Patterns&lt;/span&gt;: more advanced patterns, which may require some server-side logic and infrastructure beyond a plain old web server.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Authentication Patterns&lt;/span&gt;: these are advanced patterns that concern authentication and authorization of users and web sites, including Single Sign On, OpenID and more.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Social Patterns&lt;/span&gt;: patterns from the world of social networking, including things like OpenSocial, Facebook apps and ActivityStreams.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Perhaps using the word &#147;patterns&#148; is a bit pretentious. I&#146;m no &lt;a href=&quot;http://en.wikipedia.org/wiki/Design_Patterns&quot;&gt;gang of four&lt;/a&gt; or even one, and I don&#146;t plan to give these patterns the comprehensive treatment examples that you&#146;d find in a patterns book. I won&#146;t be providing source code examples either. Still, I think Web Integration Patterns is the right name and format, so I&#146;m sticking with it.&lt;/p&gt;

&lt;p&gt;The first pattern that I&#146;ll cover is Links. More Later...&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/more_than_bloggy</id>
        <title type="html">More than bloggy</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/more_than_bloggy"/>
        <published>2011-03-07T06:00:00+00:00</published>
        <updated>2011-06-03T00:18:13+00:00</updated> 
        <category term="Web Development" label="Web Development" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="atom" scheme="http://roller.apache.org/ns/tags/" />
        <category term="atompub" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rdf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rss" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wip" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;I&#146;ve been meaning to write on this topic for a some time and to explain how I&#146;ve gone from being an advocate of RSS/Atom feeds, Atom Publishing Protocol and things bloggy to being a proponent of Linked Data (&lt;a href=&quot;http://www.readwriteweb.com/archives/linked_data_is_blooming_why_you_should_care.php&quot;&gt;video&lt;/a&gt;), Semantic Web, RDF and other things that I previously considered to be nuisances. I&amp;#39;ve also got a new topic and blog series to announce, so here goes.&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;I&#146;ve been meaning to write on this topic for a some time and to explain how I&#146;ve gone from being an advocate of RSS/Atom feeds, Atom Publishing Protocol and things bloggy to being a proponent of Linked Data (&lt;a href=&quot;http://www.readwriteweb.com/archives/linked_data_is_blooming_why_you_should_care.php&quot;&gt;video&lt;/a&gt;), Semantic Web, RDF and other things that I previously considered to be nuisances. I&amp;#39;ve also got a new topic and blog series to announce, so here goes.&lt;/p&gt;

&lt;a href=&quot;http://rollerweblogger.org/roller/entry/tri_xml_2006_presentation&quot;&gt;&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/563b18df-9abf-4354-9fe8-ea9fd26070bd&quot; align=&quot;right&quot; alt=&quot;screenshot of Intro to RSS/Atom presentation&quot;&gt;&lt;/a&gt;

&lt;p&gt;Once upon a time, I actually said &#147;&lt;a href=&quot;http://rollerweblogger.org/roller/entry/tri_xml_2006_presentation&quot;&gt;the web is bloggy&lt;/a&gt;&#148; in conference presentations and without shame. It sounds silly and, for a blog server developer self-serving, but it&#146;s true and it&#146;s still true to this day. So much of what we do on the web can be made more useful via feeds. That&#146;s because so many things can be usefully represented as a &lt;a href=&quot;http://www.intertwingly.net/blog/1472.html&quot;&gt;well formed log&lt;/a&gt; entry, i.e. a URL, title, date, description and a chunk of content. No matter whether your web application is Flickr, Twitter or IBM/Rational Team Concert, you can enable all sorts of interesting integrations and mashups by providing feeds.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://tools.ietf.org/html/rfc5023&quot;&gt;Atom Publishing Protocol&lt;/a&gt; (APP) applied the feed concept to web APIs, using a feed to represent a collection of entries and allowing API callers to use HTTP to create, retrieve, update and delete entries. Entries could be anything of course. In the case of Google&#146;s APP-based &lt;a href=&quot;http://code.google.com/apis/gdata/&quot;&gt;GData Protocol&lt;/a&gt;, entries are Calendar Events, Picasa Photo uploads or YouTube videos. In the case of the IBM/Lotus &lt;a href=&quot;http://publib.boulder.ibm.com/infocenter/ltscnnct/v2r0/index.jsp?topic=/com.ibm.connections.25.help/c_api_common_overview.html&quot;&gt;Connections API&lt;/a&gt;, entries are Forum Posts, Social  Network Profiles, File Uploads and more.&lt;/p&gt;

&lt;h4&gt;Feeds only get you so far&lt;/h4&gt;

&lt;p&gt;I&#146;m not going to argue that &lt;a href=&quot;http://www.techcrunchit.com/2009/05/05/rest-in-peace-rss/&quot;&gt;RSS is dead&lt;/a&gt; (or Atom) because I don&amp;#39;t believe that, but the feeds approach only gets you so far. With feeds, we agree on a small set of 
common properties, e.g. URL, title, date, description and content. Not all resources on the web have those properties and many resources have a lot more. So in some cases applying Atom means forcing things to fit into the Atom model and in some cases it means inventing new properties for Atom, something that is supported by Atom format.&lt;/p&gt;

&lt;h4&gt;APIs only get you so far&lt;/h4&gt;

&lt;p&gt;I&#146;m not going to argue that APP is dead or a &lt;a href=&quot;http://bitworking.org/news/425/atompub-is-a-failure&quot;&gt;failure&lt;/a&gt; either, but APP is an API approach and, for web integration, APIs only get you so far. It&#146;s definitely a good thing for developers when a web site or application provides an API, but if you have to integrate a set of N web sites and each has it&#146;s own API and (even if they&#146;re all based on APP) you&#146;re stuck doing N x N point-to-point integrations. APIs are not necessarily the best way, and certainly not the only way, to enable integrations on the web.&lt;/p&gt;

&lt;h4&gt;Linked Data&lt;/h4&gt;

&lt;a href=&quot;http://semanticweb.com/linked-data-an-introduction_b17148&quot;&gt;
&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/6e1ca578-b5d4-4561-af0d-5a53409e941a&quot; align=&quot;right&quot; alt=&quot;Linked Data cloud diagram&quot;&gt;
&lt;/a&gt;

&lt;p&gt;Linked Data (&lt;a href=&quot;http://www.w3.org/DesignIssues/LinkedData.html&quot;&gt;W3C page&lt;/a&gt;) is a different approach. Instead of forcing everything to fit the blog model, Linked Data gives us a way to define common vocabularies of properties about resources on the web and, most importantly, the links between them. Linked Data enables integration by allowing sites to weave their resources into the interlinked web of data that is the web.&lt;/p&gt;

&lt;h4&gt;Next: Web Integration Patterns&lt;/h4&gt;

&lt;p&gt;These days, what&amp;#39;s important to me at work is &lt;a href=&quot;http://open-services.net&quot;&gt;integration&lt;/a&gt; and in my mind, Feeds, APIs and Linked Data are different &#147;patterns&#148; for web-based integrations. They can be used in complementary ways. Just as we have defined and cataloged &lt;a href=&quot;http://www.enterpriseintegrationpatterns.com/toc.html&quot;&gt;Enterprise Integration Patterns&lt;/a&gt;, I think it will be useful to do the same for Web Integration Patterns. I know I&amp;#39;ll learn something in the process. In my next posts, I&amp;#39;ll expand on this concept and after that, I&amp;#39;ll start cataloging, in an informal and bloggy way, the patterns that I&amp;#39;m familiar with. More later...&lt;/p&gt;
</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/roller_5_and_jboss_6</id>
        <title type="html">Roller 5 and JBoss 6</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/roller_5_and_jboss_6"/>
        <published>2011-01-20T18:00:15+00:00</published>
        <updated>2011-03-27T19:36:28+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="hibernate" scheme="http://roller.apache.org/ns/tags/" />
        <category term="javaee" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jboss" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;&lt;img align=&quot;right&quot; src=&quot;http://rollerweblogger.org/roller/mediaresource/d94dc4cc-d79c-423a-a9bc-ee93853ee422&quot; alt=&quot;JBoss logo&quot;&gt; In my quest to make Roller work on Java EE 6, the next server that I tackled was JBoss 6. In this blog I&amp;#39;ll describe how I approached the problem what I learned along the way.&lt;/p&gt;

&lt;h4&gt;Tested with Hibernate JPA&lt;/h4&gt;

&lt;p&gt;Roller uses &lt;a href=&quot;http://en.wikipedia.org/wiki/Java_Persistence_API&quot;&gt;JPA&lt;/a&gt; for database storage and specifically the &lt;a href=&quot;http://openjpa.apache.org/&quot;&gt;Apache OpenJPA&lt;/a&gt; implementation. I knew that JBoss uses the &lt;a href=&quot;http://www.hibernate.org&quot;&gt;Hibernate JPA&lt;/a&gt; implementation and I suspected that there would be JPA portability problems, so I decided to run Roller&amp;#39;s JUnit tests against Hibernate JPA. There were many test failures and fortunately, the failures were easy to fix.&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;&lt;img align=&quot;right&quot; src=&quot;http://rollerweblogger.org/roller/mediaresource/d94dc4cc-d79c-423a-a9bc-ee93853ee422&quot; alt=&quot;JBoss logo&quot;&gt; In my quest to make Roller work on Java EE 6, the next server that I tackled was JBoss 6. In this blog I&amp;#39;ll describe how I approached the problem what I learned along the way.&lt;/p&gt;

&lt;h4&gt;Tested with Hibernate JPA&lt;/h4&gt;

&lt;p&gt;Roller uses &lt;a href=&quot;http://en.wikipedia.org/wiki/Java_Persistence_API&quot;&gt;JPA&lt;/a&gt; for database storage and specifically the &lt;a href=&quot;http://openjpa.apache.org/&quot;&gt;Apache OpenJPA&lt;/a&gt; implementation. I knew that JBoss uses the &lt;a href=&quot;http://www.hibernate.org&quot;&gt;Hibernate JPA&lt;/a&gt; implementation and I suspected that there would be JPA portability problems, so I decided to run Roller&amp;#39;s JUnit tests against Hibernate JPA. There were many test failures and fortunately, the failures were easy to fix.&lt;/p&gt;

&lt;p&gt;Where OpenJPA is lenient, Hibernate JPA is strict about declaring transients fields as transient. So, wherever Hibernate complained, I added the appropriate transient declaration and soon all tests were passing. There were a lot of changes, but they were all trivially easy. Since I first &amp;quot;ported&amp;quot; Roller to ElipseLink JPA, its possible that some of the changes I made for EclipseLink helped with the port to Hibernate JPA.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/31c02555-27cd-4391-b951-38161b88e8c2&quot; alt=&quot;HIbernate logo&quot; align=&quot;right&quot;&gt;Those of you who are familiar with Roller&amp;#39;s history might remember that this is the second time I worked to &lt;a href=&quot;http://rollerweblogger.org/roller/entry/powered_by_struts_1_1&quot;&gt;make Roller work with Hibernate&lt;/a&gt;. Early versions of Roller ran on Hibernate until Roller 4, when we ripped it out because Apache policy does not allow LGPL. With Java EE 6, Roller can run on Hibernate and we don&amp;#39;t have to ship the Hibernate jars to do so.&lt;/p&gt;

&lt;h4&gt;Tried using the Java EE version of the Roller WAR&lt;/h4&gt;

&lt;p&gt;Since JBoss 6 is a Java EE 6 server, just like Glassfish, I figured I could use the same WAR that I created for Glassfish. That didn&amp;#39;t really work out, as you will see below. When I attempted to deploy the Roller WAR to JBoss I ran into two problems:&lt;/p&gt;

&lt;h4&gt;Problem 1: Xerces and JavaAssist&lt;/h4&gt;

&lt;p&gt;When I tried to deploy the Roller WAR to JBoss, I ran into class-cast exceptions that indicated that the version the the Xerces XML parser included with Roller conflicts with the one that is included in JBoss. I encountered a similar problem for the JavAssist jars, which are also part of Roller. This was quite surprising to me. Apparently, JBoss uses Xerces and JavAssist internally and for some reason the JBoss internals bleed through and interfere with applications; seems like a bug to me. So, we have to have a special Roller WAR for JBoss without the Xerces and JavaAssist jars in the Roller WAR.&lt;/p&gt;

&lt;h4&gt;Problem 2: JNDI Datasource Name&lt;/h4&gt;

&lt;p&gt;The next problem that I encountered was the datasource name. Roller uses the JNDI naming API to lookup its JDBC datasource. In all of the other app servers, we tell people to setup a datasource with the JNDI name &amp;#39;jdbc/rollerdb&amp;#39; but that name did not work for JBoss. For JBoss, I could only get names of names of the format &amp;quot;java:/name&amp;quot; to work. Unfortunately, with JPA the datasource name must be embedded in the &lt;code&gt;persistence.xml&lt;/code&gt; file which is embedded in a JAR file which is embedded in the Roller WAR file. It&amp;#39;s in there deep, so we have to produce a special Roller WAR for JBoss with a JBoss-friendly datasource name.&lt;/p&gt;

&lt;p&gt;*Please* correct me if I&amp;#39;m wrong. I would love to be wrong about either of these two problems.&lt;/p&gt;

&lt;h4&gt;Created special Roller WAR just for JBoss&lt;/h4&gt;

&lt;p&gt;Due to those two problems, I modified the Roller build process to create a special Roller WAR for JBoss without the OpenJPA, Xerces and JavAssist JARs and with the JBoss friendly JNDI name &lt;code&gt;java:/RollerDS&lt;/code&gt; inside all included &lt;code&gt;persistence.xml&lt;/code&gt; files.&lt;/p&gt;

&lt;h4&gt;Deployed, tested and updated the docs&lt;/h4&gt;

&lt;p&gt;Once I worked around those two problems, installing Roller on JBoss was easy. I did the whole thing via the JBoss web console, which was not familiar to me but was pretty easy to understand and use. I documented the whole process in the &lt;a href=&quot;http://people.apache.org/~snoopdave/apache-roller-5.0/roller-install-guide.pdf&quot;&gt;Roller 5 Install Guide (2MB PDF)&lt;/a&gt;, with screenshots.&lt;/p&gt;

&lt;p&gt;Next up: Roller 5 on WebSphere 8 (beta)&lt;/p&gt; 

&lt;p&gt;See also: &lt;a href=&quot;http://rollerweblogger.org/roller/entry/roller_5_and_java_ee&quot;&gt;Roller 5 and Java EE 6&lt;/a&gt; and &lt;a href=&quot;http://rollerweblogger.org/roller/entry/roller_5_and_glassfish_3&quot;&gt;Roller 5 on Glassfish 3&lt;/a&gt;.&lt;/p&gt; 
</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/roller_5_and_glassfish_3</id>
        <title type="html">Roller 5 and Glassfish 3</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/roller_5_and_glassfish_3"/>
        <published>2011-01-10T17:29:36+00:00</published>
        <updated>2011-03-27T19:36:59+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="glassfish" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="javaee" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jpa" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/1ae0d27d-6c18-4b34-89a8-2c4db15313a3&quot; alt=&quot;Duke and GlassFish&quot; align=&quot;right&quot;&gt;In my quest to make Roller work on Java EE 6, the first server that I decided to tackle was &lt;a href=&quot;http://glassfish.java.net&quot;&gt;Glassfish 3&lt;/a&gt;. In this blog I&amp;#39;ll describe how I approached the problem and what I learned along the way.&lt;/p&gt;

&lt;h4&gt;Tested with EclipseLink JPA&lt;/h4&gt;

&lt;p&gt;Roller uses &lt;a href=&quot;http://en.wikipedia.org/wiki/Java_Persistence_API&quot;&gt;JPA&lt;/a&gt; for persistence and specifically the &lt;a href=&quot;http://openjpa.apache.org/&quot;&gt;Apache OpenJPA&lt;/a&gt; implementation. I knew that GlassFish uses the &lt;a href=&quot;http://www.eclipse.org/eclipselink/&quot;&gt;EclipseLink JPA&lt;/a&gt; implementation and I suspected that there would be JPA portability problems, so I decided to run Roller&amp;#39;s JUnit tests against EclipseLink JPA. I wanted to find and fix those problems before even touching GlassFish. The tests ran and there were many JPA related failures and errors, most due to differences in the way that EclipseLink handles bi-directional relationships and the use of unmanaged objects.&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/1ae0d27d-6c18-4b34-89a8-2c4db15313a3&quot; alt=&quot;Duke and GlassFish&quot; align=&quot;right&quot;&gt;In my quest to make Roller work on Java EE 6, the first server that I decided to tackle was &lt;a href=&quot;http://glassfish.java.net&quot;&gt;Glassfish 3&lt;/a&gt;. In this blog I&amp;#39;ll describe how I approached the problem and what I learned along the way.&lt;/p&gt;

&lt;h4&gt;Tested with EclipseLink JPA&lt;/h4&gt;

&lt;p&gt;Roller uses &lt;a href=&quot;http://en.wikipedia.org/wiki/Java_Persistence_API&quot;&gt;JPA&lt;/a&gt; for persistence and specifically the &lt;a href=&quot;http://openjpa.apache.org/&quot;&gt;Apache OpenJPA&lt;/a&gt; implementation. I knew that GlassFish uses the &lt;a href=&quot;http://www.eclipse.org/eclipselink/&quot;&gt;EclipseLink JPA&lt;/a&gt; implementation and I suspected that there would be JPA portability problems, so I decided to run Roller&amp;#39;s JUnit tests against EclipseLink JPA. I wanted to find and fix those problems before even touching GlassFish. The tests ran and there were many JPA related failures and errors, most due to differences in the way that EclipseLink handles bi-directional relationships and the use of unmanaged objects.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/c55737d5-bb41-4cf5-ab58-fed6a783aa08&quot; alt=&quot;EclipseLink logo&quot; align=&quot;right&quot;&gt;Where OpenJPA is lenient about bi-directional relationships, EclipseLink requires you to manage both ends. For example, with OpenJPA you can get away with adding a bookmark to a folder with &lt;code&gt;folder.addBookmark(bookmark)&lt;/code&gt;, but with EclipseLink you&amp;#39;d also have to add &lt;code&gt;bookmark.setFolder(folder)&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Where OpenJPA is lenient about use of unmanaged objects, EclipseLink will complain bitterly whenever it finds one in a persisted collection or relationship. This was more of a problem in the tests than in the actual Roller code, which usually deals only with managed objects (i.e. those persisted to / loaded from the database and managed by the JPA implementation).&lt;/p&gt;

&lt;p&gt;I was able to fix those problems easily and move onto the next step.&lt;/p&gt;

&lt;h4&gt;Created a Roller WAR without OpenJPA&lt;/h4&gt;

&lt;p&gt;I also knew that Roller included some jars needed for Tomcat but that are not needed, or worse, problematic, on true Java EE servers. For example, we include the Apache OpenJPA implementation because Tomcat doesn&amp;#39;t have one of its own. I modified the Roller build process to create two builds. One build is for Tomcat and includes OpenJPA and the other build is for Java EE and does not.&lt;/p&gt;

&lt;h4&gt;Deployed, tested and updated the docs&lt;/h4&gt;

&lt;p&gt;Next, I figured out how to deploy Roller to GlassFish 3 via the GlassFish web console, which was pleasant to use and familiar to me. I didn&amp;#39;t run into any problems along the way and later I documented the whole process in the &lt;a href=&quot;http://people.apache.org/~snoopdave/apache-roller-5.0/roller-install-guide.pdf&quot;&gt;Roller 5 Install Guide (2MB PDF)&lt;/a&gt;, with screenshots.&lt;/p&gt;

&lt;p&gt;Next up: &lt;a href=&quot;http://rollerweblogger.org/roller/entry/roller_5_and_jboss_6&quot;&gt;Roller 5 on JBoss 6&lt;/a&gt;&lt;/p&gt; 
</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/roller_5_and_java_ee</id>
        <title type="html">Roller 5 and Java EE 6</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/roller_5_and_java_ee"/>
        <published>2011-01-05T08:15:53+00:00</published>
        <updated>2011-03-27T19:35:38+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="glassfish" scheme="http://roller.apache.org/ns/tags/" />
        <category term="javaee" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jboss" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tomcat" scheme="http://roller.apache.org/ns/tags/" />
        <category term="websphere" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;
It&amp;#39;s hard to believe, but I&amp;#39;ve been dorking around with &lt;a href=&quot;http://roller.apache.org&quot;&gt;Roller&lt;/a&gt;, the blog software that powers this site, for almost 10 years now. I started in summer 2001. In the past couple of years, I&amp;#39;ve had a lot less time to work on Roller. I devoted some of that time to mentoring student developers, which was fun and rewarding. I also spent time making Roller more consumable for developers by making it easier to build, run and deploy to modern Java app servers, which was not really fun but was definitely educational, bloggable even.&lt;/p&gt;
</summary>
        <content type="html">&lt;p&gt;
It&amp;#39;s hard to believe, but I&amp;#39;ve been dorking around with &lt;a href=&quot;http://roller.apache.org&quot;&gt;Roller&lt;/a&gt;, the blog software that powers this site, for almost 10 years now. I started in summer 2001. In the past couple of years, I&amp;#39;ve had a lot less time to work on Roller. I devoted some of that time to mentoring student developers, which was fun and rewarding. I also spent time making Roller more consumable for developers by making it easier to build, run and deploy to modern Java app servers, which was not really fun but was definitely educational, bloggable even.&lt;/p&gt;

&lt;h4&gt;Roller 5 as Java EE 6 case study&lt;/h4&gt;

&lt;p&gt;Making Roller work on the new crop of &amp;quot;modern&amp;quot; Java EE 6 servers was an interesting experience and the story makes a pretty good case study in Java EE application portability. I&amp;#39;ve put together a short series of blog posts to tell the story and this is the first, an overview. In subsequent posts I&amp;#39;ll explain the changes I had to make to get Roller working on:&lt;/p&gt; 

&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/0e4abe0f-fa37-4de2-b07c-00bf12094e55&quot; alt=&quot;glassfish logo&quot;&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;http://glassfish.java.net/downloads/3.0.1-final.html&quot;&gt;GlassFish 3&lt;/a&gt; (released June 2010)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/f409b73d-9ed0-4372-9654-5bf2b6461f01&quot; alt=&quot;jboss logo&quot;&gt; &lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;http://community.jboss.org/wiki/AS600FinalReleaseNotes&quot;&gt;JBoss 6&lt;/a&gt; (released December 2010)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/98f178c9-22d7-4d71-8be3-4d4583257e32&quot; alt=&quot;websphere logo&quot;&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;http://webspherecommunity.blogspot.com/2010/07/websphere-application-server-v80-beta.html&quot;&gt;WebSphere 8&lt;/a&gt; (beta released July 2010)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;img src=&quot;http://rollerweblogger.org/roller/mediaresource/9d655f3a-50dd-46e8-9cd2-4bd0c67800a3&quot; alt=&quot;tomcat logo&quot;&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;http://tomcat.apache.org/&quot;&gt;Tomcat&lt;/a&gt; 6 and 7 (not Java EE but Roller just has to work on Tomcat)&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;There are other Java EE 6 servers out there and there&amp;#39;s a &lt;a href=&quot;http://blogs.sun.com/theaquarium/entry/from_2_to_8_java&quot;&gt;good summary of them on The Aquarium&lt;/a&gt;; those are just the ones I had time to explore.&lt;/p&gt;

&lt;h4&gt;Overview of Java EE 6 changes&lt;/h4&gt;

&lt;p&gt;There were three categories of things I changed to accomodate Java EE 6 servers. The first is changes to the Roller code base to make Roller work on all of my targets. Most of these changes were in way Roller uses calls the Java Persistence APIs (JPA), needed because of differences in the JPA implementations used by each server. GlassFish uses EclipseLink JPA and JBoss uses Hibernate JPA.  On WebSphere and Tomcat, Apache OpenJPA is the implementation. Fortunately, nowhere did I have to use any conditional code or introduce special behavior for any platform.&lt;/p&gt;

&lt;p&gt;The second category of changes is additions to the Roller install guide to mention the special settings required to make Roller work on all targets. On some platforms, special behaviors must be enabled for Roller, for example the &amp;quot;filter compatibility&amp;quot; flag on WebSphere. I added a section to the install guide for each server and documented the details there.&lt;/p&gt;

&lt;p&gt;The third category is changes to the Roller build process to create special versions of Roller for some servers. Unfortunately, due to Tomcat not being a full Java EE server and some JBoss classloader issues, I&amp;#39;m not able to provide one Roller release that runs on all servers. The latest Roller 5 release candidate comes in three flavors, one for Tomcat 6/7, one for JBoss 6 and one for &amp;quot;Java EE&amp;quot; which is the one intended for use with Glassfish 3.1 and WebSphere 8.&lt;/p&gt;  

&lt;h4&gt;Up next: GlassFish 3&lt;/h4&gt;

&lt;p&gt;In the next post I&amp;#39;ll tell you what I had to do to get Roller running on Glassfish 3 with EclipseLink JPA.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/apache_roller_5_0_rc3</id>
        <title type="html">Apache Roller 5.0 RC3</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/apache_roller_5_0_rc3"/>
        <published>2011-01-04T08:00:00+00:00</published>
        <updated>2011-01-04T16:19:04+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="glassfish" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jboss" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jpa" scheme="http://roller.apache.org/ns/tags/" />
        <category term="websphere" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;On the last day of 2010, I made available the third release candidate for Apache Roller 5.0. The main difference between this new candidate and the previous one is that the new RC3 runs on Java EE 6 servers: Glassfish 3, JBoss 6 and Websphere 8 (currently in beta). Making this happen took a lot more work than I expected and I&amp;#39;ll blog about that over the next couple of weeks as it is an interesting case study in Java EE 6 portability.&lt;/p&gt;

&lt;p&gt;Here&amp;#39;s the announcement:&lt;/p&gt;

&lt;pre&gt;
Apache Roller 5.0 Release Candidate RC3 is now available for testing.
Note that this is NOT a release of the Apache Software Foundation or
anybody else; this release candidate is for testing purposes only and
not recommended for production.

   What&amp;#39;s new in Roller 5.0:
   &lt;a href=&quot;https://cwiki.apache.org/confluence/display/ROLLER/What&apos;s+new+in+Roller+5.0&quot;&gt;https://cwiki.apache.org/confluence/display/ROLLER/What&amp;#39;s+new+in+Roller+5.0&lt;/a&gt;

   Change list (issues resolved since 4.0)
   &lt;a href=&quot;http://bit.ly/gAhDWR&quot;&gt;http://bit.ly/gAhDWR&lt;/a&gt;

   Issues resolved since last release candidate (RC3)
   &lt;a href=&quot;http://bit.ly/dZ27Nx&quot;&gt;http://bit.ly/dZ27Nx&lt;/a&gt;

   Signed binary and source files. Also, documentation in PDF form
   &lt;a href=&quot;http://people.apache.org/~snoopdave/apache-roller-5.0/&quot;&gt;http://people.apache.org/~snoopdave/apache-roller-5.0/&lt;/a&gt;

The biggest change in RC3 is the new support for Java EE 6 application
servers: Glassfish 3, JBoss 6 and Websphere 8 (beta). I&amp;#39;ve been able
to verify that Roller runs on all of those servers, and I updated the
installation guide to explain in detail how you install on Glassfish,
JBoss and WebSphere.

If you would like to help out then please test RC3, discuss the
problems you encounter here and file specific bugs with steps to
reproduce in the Roller JIRA bug tracking system.

Thanks,
Dave
&lt;/pre&gt;

That announcement is available here: &lt;a href=&quot;http://markmail.org/message/my5wbld2xqvhqpyg&quot;&gt;http://markmail.org/message/my5wbld2xqvhqpyg
&lt;/a&gt;


</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/apache_roller_5_0_rc2</id>
        <title type="html">Apache Roller 5.0 RC2</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/apache_roller_5_0_rc2"/>
        <published>2010-10-03T10:11:39+00:00</published>
        <updated>2010-10-03T17:47:46+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="apacheroller" scheme="http://roller.apache.org/ns/tags/" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;A couple of weeks ago, I made a second release candidate available for Apache Roller 5.0. Here&amp;#39;s the announcement (also available at &lt;a href=&quot;http://s.apache.org/apacheroller50rc2&quot;&gt;http://s.apache.org/apacheroller50rc2&lt;/a&gt;):&lt;/p&gt;

&lt;blockquote&gt;&lt;pre&gt;
Apache Roller 5.0 Release Candidate RC2 is now available for testing. 
Note that this is NOT a release of the Apache Software Foundation or 
anybody else; this release candidate is for testing purposes only and 
not recommended for production.

   What&amp;#39;s new in Roller 5.0:
   &lt;a href=&quot;https://cwiki.apache.org/confluence/display/ROLLER/What&apos;s+new+in+Roller+5.0&quot;&gt;https://cwiki.apache.org/confluence/display/ROLLER/What&amp;#39;s+new+in+Roller+5.0&lt;/a&gt;

   Roller 5.0 JIRA change list:
   &lt;a href=&quot;https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12310906&amp;styleName=Html&amp;version=12313828&quot;&gt;https://issues.apache.org/jira/sec ... sion=12313828&lt;/a&gt;

   Signed binary and source files
   &lt;a href=&quot;http://people.apache.org/~snoopdave/apache-roller-5.0/&quot;&gt;http://people.apache.org/~snoopdave/apache-roller-5.0/&lt;/a&gt;

   Issues resolved since RC1:
   &lt;a href=&quot;http://bit.ly/9eWjJk&quot;&gt;http://bit.ly/9eWjJk&lt;/a&gt;

If you would like to help out then please test RC2, discuss 
the problems you encounter here and file specific bugs with steps to
reproduce in the Roller JIRA bug tracking system.&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;I&amp;#39;m running RC2 on this site and it seems to be holding up just fine so far.&lt;/p&gt;
</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/forces_and_vulnerabilities_of_the</id>
        <title type="html">Forces and vulnerabilities of the Apache model</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/forces_and_vulnerabilities_of_the"/>
        <published>2010-05-21T13:05:30+00:00</published>
        <updated>2010-05-21T23:02:11+00:00</updated> 
        <category term="Open Source" label="Open Source" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://ceki.blogspot.com/2010/05/forces-and-vulnerabilites-of-apache.html&quot;&gt;Ceki Gülcü&lt;/a&gt;: Instead of trying to learn from past failures which open discussion is supposed to encourage, Apache forges on in the path of egalitarianism. As time passes, I see attempts at institutionalizing egalitarianism instead of recognizing its inherent injustice. If egalitarianism is really at the core of the Apache way as an absolute value, then the Apache way sucks. Yay!&lt;/p&gt;
&lt;p&gt;While the one person one vote principle applies to a democracy in order to run a country for the benefit of all, the one person one vote principle is ill-suited in a purported meritocracy the size of Apache. If it &lt;em&gt;must&lt;/em&gt; be &amp;quot;one developer one vote&amp;quot;, then the word &lt;em&gt;meritocracy&lt;/em&gt; cannot be honestly ascribed to Apache.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Very interesting discussion and comments on the dynamics of meritocracy at the Apache Software Foundation from Ceki Gülcü.&lt;/p&gt;
</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/new_era_for_jspwiki</id>
        <title type="html">New era for JSPWiki</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/new_era_for_jspwiki"/>
        <published>2008-11-26T08:46:20+00:00</published>
        <updated>2009-01-06T07:03:43+00:00</updated> 
        <category term="Social Software" label="Social Software" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jspwiki" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;img src=&quot;http://rollerweblogger.org/roller/resource/jspwiki_logo_s.png&quot; align=&quot;right&quot; alt=&quot;JSPWiki logo&quot;&gt;

&lt;blockquote&gt;
&lt;a href=&quot;http://www.ecyrd.com/ButtUgly/wiki/Main_blogentry_261108_2&quot;&gt;Janne Jalkanen&lt;/a&gt;: We are now beginning a whole new era with becoming an Apache project and JSPWiki v3, which will signal the first major overhaul of the entire software since v2.0 in 2002. We&amp;#39;ve got a bunch of good committers (with a new one added this weekend - welcome, Florian!) and a bunch of pretty exciting things we want to do.
&lt;/blockquote&gt;

&lt;p&gt;I&amp;#39;m so happy to see &lt;a href=&quot;http://www.jspwiki.org&quot;&gt;JSPWiki&lt;/a&gt; thrive &lt;a href=&quot;http://incubator.apache.org/jspwiki/&quot;&gt;at Apache&lt;/a&gt;, even in the incubator. You may remember that I wrote to Janne back in Summer 2007 and suggested the move, and I&amp;#39;ve &lt;a href=&quot;http://rollerweblogger.org/roller/entry/jspwiki_apache&quot;&gt;crowed about it&lt;/a&gt; before, but &lt;a href=&quot;http://www.linkedin.com/pub/0/2a0/71b&quot;&gt;Craig Russell&lt;/a&gt; is the one who stepped up to mentor the project and, from what I&amp;#39;ve seen, he&amp;#39;s doing a great job.&lt;/p&gt;
</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/apache_abdera_graduates</id>
        <title type="html">Atom news: Apache Abdera graduates</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/apache_abdera_graduates"/>
        <published>2008-11-21T15:54:48+00:00</published>
        <updated>2009-01-06T07:04:46+00:00</updated> 
        <category term="Java" label="Java" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="atom" scheme="http://roller.apache.org/ns/tags/" />
        <category term="atompub" scheme="http://roller.apache.org/ns/tags/" />
        <category term="feeds" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="opensource" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rome" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;img src=&quot;http://rollerweblogger.org/roller/resource/atom-logo75px.gif&quot; align=&quot;right&quot; alt=&quot;Atom logo&quot; title=&quot;Atom logo&quot;&gt;

&lt;p&gt;Congratulations to the &lt;a href=&quot;http://incubator.apache.org/abdera/&quot;&gt;Apache Abdera&lt;/a&gt; team, who&amp;#39;ve just &lt;a href=&quot;http://mail-archives.apache.org/mod_mbox/incubator-abdera-dev/200811.mbox/%3C4585c4a60811191238t52bd9840q845653578eb0690d@mail.gmail.com%3E&quot;&gt;graduated&lt;/a&gt; to full Apache top level project status. The don&amp;#39;t have the new site at &lt;b&gt;abdera.apache.org&lt;/b&gt; up yet and they&amp;#39;re still not quite at 1.0 yet, but this is a  major milestone. They&amp;#39;ve got the best Atom format and protocol toolkit around, &lt;a href=&quot;http://rollerweblogger.org/roller/entry/rome_vs_abdera&quot;&gt;in my opinion&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;via &lt;a href=&quot;http://asdf.blogs.com/asdf/2008/11/abdera-graduation.html&quot;&gt;Garett&lt;/a&gt; and &lt;a href=&quot;http://www.snellspace.com/wp/?p=979&quot;&gt;James&lt;/a&gt;.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/roller_status3</id>
        <title type="html">Roller status</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/roller_status3"/>
        <published>2008-08-18T18:27:40+00:00</published>
        <updated>2008-08-19T01:27:40+00:00</updated> 
        <category term="Roller" label="Roller" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="opensource" scheme="http://roller.apache.org/ns/tags/" />
        <category term="roller" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;img src=&quot;http://rollerweblogger.org/roller/resource/apachelogo.gif&quot; alt=&quot;feather logo&quot;&gt;

&lt;p&gt;If you want the lowdown on what&amp;#39;s going on with Roller community health, ongoing work and upcoming releases then check out the &lt;a href=&quot;http://cwiki.apache.org/confluence/x/Q2sB&quot;&gt;Apache Roller August 2008 Board Report&lt;/a&gt;.&lt;/p&gt;


</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/six</id>
        <title type="html">Six</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/six"/>
        <published>2008-03-08T17:30:36+00:00</published>
        <updated>2008-03-09T01:30:37+00:00</updated> 
        <category term="Open Source" label="Open Source" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="sun" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;By my count that&amp;#39;s how many Apache members work at Sun. I thought I had a complete count, but &lt;a href=&quot;http://bahumbug.wordpress.com/2008/03/08/sun-and-apache/&quot;&gt;Nick Kew&amp;#39;s recent&lt;/a&gt; post revealed a sixth (see the comments). Here&amp;#39;s the list:&lt;/p&gt;
&lt;ul&gt;
   &lt;li&gt;Craig McClanahan&lt;/li&gt;
   &lt;li&gt;Craig Russell&lt;/li&gt; 
   &lt;li&gt;Dave Johnson&lt;/li&gt;
   &lt;li&gt;Jim Winstead&lt;/li&gt;
   &lt;li&gt;Nick Kew&lt;/li&gt;
   &lt;li&gt;Ted Leung&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Know of any other Sun employees that are Apache members?&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/welcome_to_sun</id>
        <title type="html">Welcome to Sun!</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/welcome_to_sun"/>
        <published>2008-03-04T18:33:38+00:00</published>
        <updated>2008-03-05T02:33:38+00:00</updated> 
        <category term="Sun" label="Sun" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="mysql" scheme="http://roller.apache.org/ns/tags/" />
        <category term="sun" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;It&amp;#39;s great to be welcoming new folks to Sun, especially when they&amp;#39;re brilliant people like &lt;a href=&quot;http://www.sauria.com/blog/2008/03/03/the-sun-is-going-to-shine-on-python/&quot;&gt;Ted Leung&lt;/a&gt; and &lt;a href=&quot;http://bahumbug.wordpress.com/&quot;&gt;Nick Kew&lt;/a&gt;, both of whom, by the way, are members of the &lt;a href=&quot;http://apache.org/&quot;&gt;Apache Software Foundation&lt;/a&gt;. I met Ted at ApacheCon US 2004 in Vegas and he answered all my questions about the implications of moving Roller to the ASF. And I met Nick at ApacheCon EU 2006 in Dublin and we chatted, over a couple of pints of Guiness, about the perils and pleasures of working from home and other things.&lt;/p&gt;

&lt;p&gt;I&amp;#39;m also pretty damn pleased to be part of the MySQL welcoming committee, AKA the SunVisor program, and paired-up with Chuck Bell of MySQL. He&amp;#39;s the author of &lt;a href=&quot;http://www.amazon.com/Expert-MySQL-Dr-Charles-Bell/dp/1590597419&quot;&gt;Expert MySQL&lt;/a&gt;. I&amp;#39;ll be answering his questions about Sun and, I hope, learning a thing or two about MySQL in the process.&lt;/p&gt;

&lt;p&gt;Welcome to Sun guys!&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/springsource_and_covalent_good_thing</id>
        <title type="html">SpringSource and Covalent: good thing for Apache?</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/springsource_and_covalent_good_thing"/>
        <published>2008-01-30T09:27:34+00:00</published>
        <updated>2008-01-30T17:27:36+00:00</updated> 
        <category term="Open Source" label="Open Source" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="opensource" scheme="http://roller.apache.org/ns/tags/" />
        <category term="roller" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;&lt;a href=&quot;http://www.springsource.com&quot;&gt;SpringSource&lt;/a&gt;, the company behind the Spring Framework, has purchased &lt;a href=&quot;http://www.covalent.net/&quot;&gt;Covalent&lt;/a&gt;, a company that provides support for Apache projects. This popped up on my radar because Covalent offers support contracts for Roller and in fact, SpringSource CEO Rod Johnson mentioned Roller specifically when talking about the deal (emphasis mine):&lt;/p&gt;

&lt;blockquote&gt;&amp;lt;a href=
&amp;quot;http://www.informationweek.com/news/showArticle.jhtml?articleID=205920751&amp;quot;&amp;gt;Rod Johnson: &amp;quot;We want to support the open source software that people want to use,&amp;quot; including the Geronimo application server, the Axis Web Services Framework from Apache, and the &lt;b&gt;Apache Roller Blog&lt;/b&gt; multi-user blogging software.&amp;quot;
&lt;/blockquote&gt;

&lt;p&gt;Sounds like a good thing and hopefully it will improve the support story for all Apache products. In fact, it could be a really good thing for Apache projects because Rod&amp;#39;s philosophy is that you can&amp;#39;t support software unless you are one of the software&amp;#39;s creators. &lt;/p&gt;

&lt;blockquote&gt;&amp;lt;a href=
&amp;quot;http://www.infoq.com/news/2007/06/open-source-models&amp;quot;&amp;gt;Rod Johnson: 
&amp;quot;You can&amp;#39;t divorce the process of maintaining software from the process of creating software...That&amp;#39;s not the future of enterprise open source - unless open source has no future&amp;quot;&lt;/blockquote&gt;

&lt;p&gt;Based on that, we can assume that SpringSource will now be paying committers to do creative work on Roller and other Apache projects so that they can provide the best maintenance and support of those same projects. Right? Maybe I&amp;#39;m too naive -- after all, I figured having Roller in Lotus Connections meant IBM would be contributing.&lt;p&gt;
&lt;/p&gt;&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/apache_shindig_voting_in_progress</id>
        <title type="html">Apache Shindig voting in progress and more OpenSocial details emerge</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/apache_shindig_voting_in_progress"/>
        <published>2007-11-30T12:48:25+00:00</published>
        <updated>2007-12-01T01:21:02+00:00</updated> 
        <category term="Open Source" label="Open Source" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ning" scheme="http://roller.apache.org/ns/tags/" />
        <category term="opensocial" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;I wrote about Shindig before, it&amp;#39;s a new open source project to implement the &lt;a href=&quot;http://code.google.com/apis/opensocial/&quot;&gt;Google OpenSocial APIs&lt;/a&gt;. 

Well, now the official voting to accept the Shindig project into the &lt;a href=&quot;http://incubator.apache.org/&quot;&gt;Apache Incubator&lt;/a&gt; is in progress and some interesting details have emerged in the latest version of &lt;a href=&quot;http://markmail.org/message/6hed4akb4jefcdur&quot;&gt;the proposal&lt;/a&gt;. 

First, as you can see by the initial list of committers in the proposal Google has joined the Shindig effort in force. 

Second, the proposal says that Shindig will be the reference implementation of the OpenSocial APIs. 

And third, Shindig will not only include the client-side JavaScript container but also a Java back-end. 

Brian McAllister has already made some &amp;quot;gnarly&amp;quot; initial client-side &lt;a href=&quot;http://markmail.org/message/ypkv4qaksbmpmonh&quot;&gt;container code&lt;/a&gt; available, I can&amp;#39;t wait to see the Google contribution.&lt;/p&gt; </content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/apachecon_us_2007_wrapup</id>
        <title type="html">ApacheCon US 2007 wrapup</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/apachecon_us_2007_wrapup"/>
        <published>2007-11-20T17:42:51+00:00</published>
        <updated>2008-01-04T19:44:47+00:00</updated> 
        <category term="Open Source" label="Open Source" />
        <category term="apache" scheme="http://roller.apache.org/ns/tags/" />
        <category term="apachecon" scheme="http://roller.apache.org/ns/tags/" />
        <category term="apacheconus2007" scheme="http://roller.apache.org/ns/tags/" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">I spent last week at the ApacheCon US 2007 conference in Atlanta, Georgia. Here&amp;#39;s a write up of some of my experiences there.&amp;nbsp;</summary>
        <content type="html">&amp;lt;img src=&amp;quot;http://rollerweblogger.org/roller/resource/acus2007-badge.JPG&amp;quot; alt=&amp;quot;ApacheCon badge&amp;quot; 
width=&amp;quot;150px&amp;quot; vspace=&amp;quot;15px&amp;quot; hspace=&amp;quot;15px&amp;quot; align=&amp;quot;right&amp;quot; /&amp;gt;

&lt;p&gt;I spent last week at the ApacheCon US 2007 conference in Atlanta, Georgia. Here&amp;#39;s a write up of some of my experiences there.&lt;/p&gt;

&lt;h3&gt;The Hackathon&lt;/h3&gt;

&lt;p&gt;The Hackathon is a two day event. For those who don&amp;#39;t know what a hackathon is, I&amp;#39;ll explain how it works. A room with about 20 large round tables, wireless internet and plenty of power strips is provided. Folks show up, plug-in, start working and chatting with each other about projects and other random topics. Sometimes they cluster by project, Struts guys around one table and Geronimo guys at the next, but usually there&amp;#39;s a good mix at each table. Sometimes groups have specific goals like &amp;quot;ship version 2.0&amp;quot; in mind, but usually folks are just working, sharing knowledge and getting to know each other. At various times pizza, soda, breakfast pastries, beer, coffee and/or wine is carted into the room -- so there&amp;#39;s not much reason to leave except for things like fresh air, sunlight and sanity.&lt;/p&gt;

&lt;p&gt;I had a couple of interesting conversations at the Hackathon. I spent some time talking to &lt;a href=&quot;http://blog.skife.org/&quot;&gt;Brian McAllister&lt;/a&gt; about his &lt;a href=&quot;http://markmail.org/message/yzkaf33e4v3ajfwx&quot;&gt;Shindig proposal&lt;/a&gt;, which I&amp;#39;ve &lt;a href=&quot;http://rollerweblogger.org/roller/entry/shindig_open_source_implementation_of&quot;&gt;already mentioned&lt;/a&gt;. I also spoke with David Jencks about getting better Role Based Access Control (RBAC) in Java EE to support social software like blogs, wikis and social network applications because static roles hard-coded into web.xml just won&amp;#39;t do.&lt;/p&gt;


&lt;h3&gt;Roller and the Roller/Struts2 BOF&lt;/h3&gt;

&lt;p&gt;As usual, I attended ApacheCon to promote and represent Roller and I did so in my talk, at the Roller/Struts 2 BOF, at the Sun booth and wherever else I could. As I &lt;a href=&quot;http://rollerweblogger.org/roller/entry/roller_and_blogs_as_a&quot;&gt;mentioned before&lt;/a&gt;, my talk on Roller and blogs as a web development platform went well. I had updated my talk to include an example of how to post to a blog using Abdera and I urged folks to stick around for &lt;a href=&quot;http://asdf.blogs.com/&quot;&gt;Garrett Rooney&lt;/a&gt;&amp;#39;s &lt;a href=&quot;http://incubator.apache.org/abdera&quot;&gt;Abdera&lt;/a&gt; talk, which followed mine in the same room.&lt;/p&gt;

&lt;p&gt;The BOF session also went well. &lt;a href=&quot;http://raibledesigns.com&quot;&gt;Matt Raible&lt;/a&gt; and &lt;a href=&quot;http://www.jroller.com/mrdon/&quot;&gt;Don Brown&lt;/a&gt; organized the session and all I had to do was show up and enjoy the good company and the Atlassian provided beer, wine and nibbles. About ten people showed up and we talked about a variety of topics including user management in Roller, the growing similarity of Struts 2, Spring MVC and other Java web frameworks and then my wife dragged me away from the fun. By the way, Don works for Atlassian on the new &lt;a href=&quot;http://www.jira.com&quot;&gt;JIRA Studio suite&lt;/a&gt;, which, I believe, is going to give Collabnet, SourceForge Enterprise and even the likes of IBM Jazz and Microsoft Team System some serious competition.&lt;/p&gt;


&lt;h3&gt;Roller the Java Content Repository (JCR) API&lt;/h3&gt;

&lt;p&gt;The idea of using a content management system to store Roller content keeps on coming up. At ApacheCon EU earlier this year, I spent some time talking to Lars Trieloff (who now works for CMS vendor &lt;a href=&quot;http://www.day.com/&quot;&gt;Day Software&lt;/a&gt;) about implementing the Roller back-end interfaces using the &lt;a href=&quot;http://jcp.org/en/jsr/detail?id=170&quot;&gt;Java Content Repository&lt;/a&gt; (JCR) APIs instead of the &lt;a href=&quot;http://java.sun.com/javaee/technologies/persistence.jsp&quot;&gt;Java Persistence API&lt;/a&gt; (JPA) that we use now. At this ApacheCon, &lt;a href=&quot;http://www.us.apachecon.com/us2007/program/speaker/4776&quot;&gt;Noel Bergman&lt;/a&gt; brought up the topic a couple of times and pointed out that Day Software, has blog and wiki modules that are both backed by JCR. We could do the same thing: create version of Apache Roller and Apache JSPWiki (incubating) that share the same content repository.&lt;/p&gt;

&lt;p&gt;Later, &lt;a href=&quot;http://jukkaz.wordpress.com/&quot;&gt;Jukka Zitting&lt;/a&gt; (who also works for Day Software), suggested the idea of implementing JPA itself with JCR, thus allowing Roller to store its content in a CMS in a totally transparent fashion. This topic is interesting to me, but I don&amp;#39;t fully understand the benefits of backing blogs and wikis with JCR. What new use cases would this support? How do the interesting features of JCR, like versioning for example, bubble up through Roller -- especially if Roller is to support both RDBMS and CMS back-ends?&lt;/p&gt;

&lt;p&gt;And by the way, Day is not the only company building interesting products around JCR and the &lt;a href=&quot;http://jackrabbit.apache.org/&quot;&gt;Apache Jackrabbit&lt;/a&gt; JCR implementation. Hippo CTO &lt;a href=&quot;http://blogs.hippo.nl/arje/&quot;&gt;ArjÃ© Cahn&lt;/a&gt; and others from Hippo were &lt;a href=&quot;http://www.hippo.nl/en/agenda,2007/apachecon.html&quot;&gt;present at ApacheCon&lt;/a&gt;, talking about their CMS product and related Apache projects.&lt;/p&gt;


&lt;h3&gt;The REST sessions and the Struts 2 REST plugin&lt;/h3&gt;

&lt;a href=&quot;http://struts.apache.org/2.x&quot;&gt;
&lt;img src=&quot;http://struts.apache.org/2.x/images/struts2-merger2.png&quot; alt=&quot;struts 2 logo&quot; align=&quot;right&quot;&gt;
&lt;/a&gt;

&lt;p&gt;Thursday afternoon there was series of REST talks, starting with &lt;a href=&quot;http://en.wikipedia.org/wiki/Roy_Fielding&quot;&gt;Roy Fielding&lt;/a&gt; father of REST, then &lt;a href=&quot;http://sanjiva.weerawarana.org/&quot;&gt;Sanjiva Weerawarana&lt;/a&gt; defender of WS-*, &lt;a href=&quot;http://netzooid.com/blog&quot;&gt;Dan Diephouse&lt;/a&gt; and &lt;a href=&quot;http://www.jroller.com/mrdon/&quot;&gt;Don Brown&lt;/a&gt;. Roy&amp;#39;s talk was standing room only and the other REST talks were quite popular as well. Hearing from REST masters as great, but Don&amp;#39;s talk was the one most relevant to my work (since I&amp;#39;m a Struts 2 user). &lt;/p&gt;

&lt;p&gt;Don talked about the new &lt;a href=&quot;http://struts.apache.org/2.x/docs/rest-plugin.html&quot;&gt;REST plugin&lt;/a&gt; he has developed for &lt;a href=&quot;http://struts.apache.org/2.x/&quot;&gt;Struts 2&lt;/a&gt;, which looks like a wonderful thing. It builds on the existing CodeBehind plugin to give you Ruby-on-Rails like convention-over-configuration and in most cases no Struts configuration or properties files are necessary. From my point-of-view, it&amp;#39;s just another reason to choose Struts 2 over JSF, which, as &lt;a href=&quot;http://www.dehora.net/journal/2007/11/19/java-rest/&quot;&gt;Bill de hÃ&#147;ra points out&lt;/a&gt;, &amp;quot;is clearly not focused on or suitable for working in the REST style to the extent REST principles seem to be actively excluded from the design.&amp;quot;  See also: &lt;a href=&quot;http://raibledesigns.com/rd/entry/go_light_with_apache_struts&quot;&gt;Matt Raible&amp;#39;s notes on the Struts 2 REST plugin&lt;/a&gt; and Don&amp;#39;s &lt;a href=&quot;http://wiki.apache.org/apachecon-data/attachments/Us2007OnlineSessionSlides/attachments/ApacheConUS2007-Struts2REST.pdf.zip&quot;&gt;slides&lt;/a&gt; (a zipped PDF file).&lt;/p&gt;


&lt;h3&gt;Lucene and search sessions&lt;/h3&gt;

&lt;p&gt;On Friday there was a series of talks related to &lt;a href=&quot;http://lucene.apache.org&quot;&gt;Apache Lucene&lt;/a&gt; and related projects such as Solr. These talks seemed to be quite popular as well. I attended the Solr talk. &lt;a href=&quot;http://lucene.apache.org/solr/&quot;&gt;Apache Solr&lt;/a&gt; is a version of the Lucene search engine that is packaged as an easy to install and easy to use web application. 
The &lt;a href=&quot;http://us.apachecon.com/us2007/program/talk/1992&quot;&gt;talk&lt;/a&gt; demonstrated all of the things you can do with Solr without writing any Java code and it was pretty impressive. I also spoke with Ken Krugler of &lt;a href=&quot;http://corp.krugle.com/company/&quot;&gt;Krugle&lt;/a&gt;, the source code search engine, about search in Roller, something that he&amp;#39;s been thing and &lt;a href=&quot;http://blog.krugle.com/?p=271&quot;&gt;writing about lately&lt;/a&gt;.&lt;/p&gt;


&lt;h3&gt;Couple of end notes re: Atlanta&lt;/h3&gt;

&lt;a href=&quot;http://www.flickr.com/photos/snoopdave/2044103505/&quot; title=&quot;Atlanta skyline by snoopdave, on Flickr&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2010/2044103505_e003894b52_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot; alt=&quot;Atlanta skyline&quot; align=&quot;right&quot; hspace=&quot;15px&quot; vspace=&quot;15px&quot;&gt;&lt;/a&gt;

&lt;p&gt;First, the venue. &lt;a href=&quot;http://www.Westin.com/Peachtree&quot;&gt;The Westin&lt;/a&gt; is an impressive building, it&amp;#39;s the tallest hotel in the western hemisphere and the rotating bar and restaurant at the top are a lot of fun, with relatively good food and well worth a visit. The hotel itself, though, does not seem to be all that well managed or maintained. The carpets are a little spotty and the furniture is a little worn. Generally, that kind of stuff doesn&amp;#39;t bother me much, but I can see why folks might complain (and they did).&lt;/p&gt;

&lt;p&gt;Second item: a good dining experience. On Monday night, a big group of hackathon attendees ventured out to look for &lt;a href=&quot;http://www.yelp.com/biz/bpYsgz3J62i0iT03atmVTA&quot;&gt;Rare&lt;/a&gt;, billed as a soul-food tapas restaurant. It was quite a long walk from the Westin but we managed to get there with help from Greg Stein&amp;#39;s iPhone and some overly helpful folks we ran into on the street. Rare was simply wonderful so next time you&amp;#39;re in Atlanta, skip Pittypat&amp;#39;s Portch and give Rare a try instead.&lt;/p&gt;

&lt;p&gt;And third, MARTA. The travel info I received from the ApacheCon folks recommended taking a shuttle bus from the airport to the Westin, but that&amp;#39;s not the best way to go. The MARTA train is a much better way to go -- $4 for a the round trip, it&amp;#39;s quick and there&amp;#39;s no need to tip. &lt;/p&gt;

&lt;h3&gt;Wrapping up&lt;/h3&gt;

&lt;p&gt;That brings me to the end of my notes, so it&amp;#39;s time to wrap up. As usual, ApacheCon was a great experience and I hope to make it to the next one in Amsterdam this coming April.&lt;/p&gt;

&lt;p&gt;One more thing. You can find many of the session slides on the &lt;a href=&quot;http://wiki.apache.org/apachecon/Us2007OnlineSessionSlides&quot;&gt;ApacheCon wiki&lt;/a&gt;.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/re_jspwiki_apache</id>
        <title type="html">re: JSPWiki@Apache?</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/re_jspwiki_apache"/>
        <published>2007-09-18T22:26:13+00:00</published>
        <updated>2007-09-19T05:26:13+00:00</updated> 
        <category term="Open Source" label="Open Source" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="foss" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jspwiki" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wikis" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;Congrats are also in order for the JSPWiki team. 

As &lt;a href=&quot;http://www.ecyrd.com/ButtUgly/wiki/Main_blogentry_180907_1&quot;&gt;Janne Jalkanen&lt;/a&gt; notes, &lt;a href=&quot;http://jspwiki.org&quot;&gt;JSPWiki&lt;/a&gt; was accepted into the Apache Incubator yesterday. 

I&amp;#39;m proud to be one of the four mentors who will guide the project through the incubation process. Janne and the JSPWiki team put together a great proposal and I think it was clear to everybody involved in the vote that these folks know what they&amp;#39;re doing. They&amp;#39;ll master the Apache way in no time.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/jspwiki_apache</id>
        <title type="html">JSPWiki@Apache?</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/jspwiki_apache"/>
        <published>2007-08-07T11:09:38+00:00</published>
        <updated>2007-09-21T18:38:38+00:00</updated> 
        <category term="Open Source" label="Open Source" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="foss" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wiki" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;blockquote&gt;
&lt;a href=&quot;http://jspwiki.org&quot;&gt;
&lt;img src=&quot;http://www.jspwiki.org/images/jspwiki_logo_s.png&quot; align=&quot;right&quot; alt=&quot;jspwiki logo&quot;&gt;&lt;/a&gt;

&lt;p&gt;&lt;a href=&quot;http://www.jspwiki.org/wiki/ApacheJSPWikiManifesto&quot;&gt;Apache JSPWiki Manifesto&lt;/a&gt;: This idea has been brought up before, but so far it has not really been an issue. However, this looks like the time when it would be possible to accomplish this.&lt;/p&gt;

&lt;p&gt;JSPWiki code base is old, and it needs some refactoring. This refactoring includes things like moving to Java 5, fixing the metadata engine, replacing the backend with something scalable, and in general removing all the cruft that has been accumulated over time. This requires that we break compatibility with existing plugins and other components. Not badly, but to some degree.&lt;/p&gt;

&lt;p&gt;Also, JSPWiki as an open source software project is growing slowly but steadily. However, the wiki world is moving rapidly, and wikis have been adopted widely. JSPWiki has become a tool for a great many companies, who are relying on it in their daily business. This is a lot for a hobby project lead by a &amp;quot;benevolent dictator&amp;quot; -model. Therefore, it is time for JSPWiki to mature to a &amp;quot;real&amp;quot; open source software project to be a serious contender in the wiki world.&lt;/p&gt;

&lt;p&gt;To accomplish both of these goals needs a major shift in how JSPWiki is managed and who &amp;quot;owns&amp;quot; it, in a sense. Therefore, we (the people who have been committing source code) think that Apache would be a good choice, and have decided that we will try to submit JSPWiki into the Apache incubation process, with the goal of graduating as a top-level project.&lt;/p&gt; 
&lt;/blockquote&gt;

&lt;p&gt;
I&amp;#39;ve been a &lt;a href=&quot;http://jspwiki.org&quot;&gt;JSPWiki&lt;/a&gt; (and &lt;a href=&quot;http://www.ecyrd.com/ButtUgly/&quot;&gt;Janne Jalkanen&lt;/a&gt;) fan for years now. 

It&amp;#39;s my favorite Java-based wiki so I&amp;#39;m pretty excited that the dev team is &amp;lt;a href=
&amp;quot;http://ecyrd.com/pipermail/jspwiki-dev/2007-August/000508.html&amp;quot;&amp;gt;preparing a proposal to move the project to Apache.

I think this will be a great move and will ensure that the project continues to grow and continues to be a strong contender in the enterprise wiki space.

I&amp;#39;m more than willing to help with that proposal and to help out in the &lt;a href=&quot;http://incubator.apache.org/&quot;&gt;Incubator&lt;/a&gt;.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/apache_openjpa_graduates</id>
        <title type="html">Apache OpenJPA graduates</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/apache_openjpa_graduates"/>
        <published>2007-05-22T08:50:28+00:00</published>
        <updated>2007-05-22T15:50:28+00:00</updated> 
        <category term="Java" label="Java" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jpa" scheme="http://roller.apache.org/ns/tags/" />
        <category term="orm" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;Congrats to the OpenJPA team.&lt;br&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;a href=&quot;http://jroller.com/page/pcl?entry=openjpa_graduates_from_the_apache&quot;&gt;Patrick Linksey&lt;/a&gt;: Last week, OpenJPA graduated from the Apache incubator, meaning that
it&amp;#39;s now a fully-fledged Apache project. We&amp;#39;re graduating to a
top-level project, so once the infrastructure administrivia gets worked
out, the new URL will be http://openjpa.apache.org.&lt;p&gt;I&amp;#39;d like to thank Craig Russell for pushing the project through the
last mile of graduation details, and our incubation mentors (Brian
McAllister, Eddie O&amp;#39;Neil, and Geir Magnusson) for all their help
transitioning into the Apache world.&lt;/p&gt;&lt;/blockquote&gt;




&lt;p&gt;I&amp;#39;m pushing to replace Hibernate with JPA in Roller and OpenJPA seems the most likely candidate, so I&amp;#39;m glad to hear the community is thriving.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/apachecon_eu_2007_wrap_up</id>
        <title type="html">ApacheCon EU 2007 wrap-up</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/apachecon_eu_2007_wrap_up"/>
        <published>2007-05-06T23:09:36+00:00</published>
        <updated>2007-05-07T06:09:36+00:00</updated> 
        <category term="Open Source" label="Open Source" />
        <category term="apache" scheme="http://roller.apache.org/ns/tags/" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="foss" scheme="http://roller.apache.org/ns/tags/" />
        <category term="roller" scheme="http://roller.apache.org/ns/tags/" />
        <category term="sun" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;As usual &lt;a href=&quot;http://www.eu.apachecon.com&quot;&gt;ApacheCon&lt;/a&gt; was a blast. I showed-up on Tuesday, made myself at home in the hackathon room and started reconnecting with old friends and meeting new ones. I arrived at the members reception a little late and missed the beer, but was not too late to meet &lt;a href=&quot;http://weblogs.goshaky.com/weblogs/lars/&quot;&gt;Lars Trieloff&lt;/a&gt; of &lt;a href=&quot;http://www.mindquarry.org&quot;&gt;Mindquarry&lt;/a&gt;, a startup that&amp;#39;s working on an interesting open source product suite that combines content management, task management and wiki functionality. Behind the scenes the product combines Subversion, Apache Jackrabbit and other open source products. Apparently everything is tied together via the Java Content Repository (JCR) API and that&amp;#39;s why Lars is interested in the possibility of hooking Roller up with a JCR backend.&lt;br&gt;&lt;br&gt;Talks began Wednesday and I sat in the business track for most of the day. I particularly enjoyed Rebecca Hansen&amp;#39;s talk &lt;a href=&quot;http://www.eu.apachecon.com/program/talk/18&quot;&gt;Better than free: Strategic opportunities in open source&lt;/a&gt; and Bill Stoddards talk on &lt;a href=&quot;http://www.eu.apachecon.com/program/talk/19&quot;&gt;Best Practices for Incorporating Open Source Code in Commercial Production&lt;/a&gt;. I also enjoyed Alexandru Popescu talk on &lt;a href=&quot;http://www.eu.apachecon.com/program/talk/45&quot;&gt;Up to Speed with Java Content Repository API and Jackrabbit&lt;/a&gt;. I attended Stefano Machacci&amp;#39;s excellent &lt;a href=&quot;http://www.eu.apachecon.com/program/talk/37&quot;&gt;Community Building Practices&lt;/a&gt; talk again -- I think it should be required for all Apache contributors.&lt;br&gt;&lt;br&gt;Thursday night was the Sun party at Lloyd Hotel, which was was quite successful. I had an interesting Roller-related chat with Paolo Castagna of HP, who is investigating new ways to integrate blogs, planets and wikis -- so we had a lot to talk about. I&amp;#39;m hoping he&amp;#39;ll find that Roller is a good foundation for his work and encouraged him to collaborate with us via the Roller mailing lists. By the way, like Lars Trieloff, he is also interested in JCR as a back-end for blog/wiki data.&lt;br&gt;&lt;br&gt;My talk &lt;a href=&quot;http://www.eu.apachecon.com/program/talk/87&quot;&gt;Roller and blogs as a web development platform&lt;/a&gt; was scheduled for 10:30 Friday morning. It didn&amp;#39;t go so well. Power went out at around 10AM and didn&amp;#39;t come back until about 20 minutes into the talk. That left me a bit frazzled and feeling rushed, so I don&amp;#39;t think I gave my best performance. If you&amp;#39;d like more information on the talk, you can find the outline &lt;a href=&quot;http://rollerweblogger.org/roller/entry/apacheconeu_roller_and_blogs_as&quot;&gt;here&lt;/a&gt; and the slides &lt;a href=&quot;http://wiki.apache.org/apachecon-data/attachments/Eu2007OnlineSessionSlides/attachments/ApacheConEU-2007-RollerPlatformTalk.pdf&quot;&gt;here&lt;/a&gt; (1.6MB PDF).
&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://rollerweblogger.org/roller/entry/apachecon_eu</id>
        <title type="html">Arrived at ApacheCon EU</title>
        <author><name>Dave Johnson</name></author>
        <link rel="alternate" type="text/html" href="https://rollerweblogger.org/roller/entry/apachecon_eu"/>
        <published>2007-05-01T07:03:00+00:00</published>
        <updated>2007-05-01T14:16:17+00:00</updated> 
        <category term="Open Source" label="Open Source" />
        <category term="amsterdam" scheme="http://roller.apache.org/ns/tags/" />
        <category term="apachecon" scheme="http://roller.apache.org/ns/tags/" />
        <category term="asf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="roller" scheme="http://roller.apache.org/ns/tags/" />
        <category term="vacation" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;Vacation is over and it&amp;#39;s back to work today. I rode the tram up to Amsterdam Central Station to see Andi off, checked out of our vacation hotel and made my way up to the Movenpick Hotel for &lt;a href=&quot;http://www.eu.apachecon.com/&quot;&gt;ApacheCon EU&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I&amp;#39;m in the ApacheCon hackathon room now working to clear my in-box,
catch-up on blogs and figure out what work things need my (rather
limited) attention this week.&lt;br&gt;&lt;/p&gt;&lt;p&gt;Vacation was wonderful, by the way. I didn&amp;#39;t do any travel blogging on this trip, but I&amp;#39;ve taken about 200 photos and uploaded some of the best to my &lt;a href=&quot;http://flickr.com/photos/snoopdave&quot;&gt;Flickr account&lt;/a&gt;. I took a bunch of nice shots of the Queens Day festivities yesterday. and the ad hoc boat parades. I&amp;#39;ve also been building a Google map of our travels, annotated with photos and comments. I&amp;#39;ll share that link later this week once it&amp;#39;s more complete.&lt;/p&gt;</content>
    </entry>
</feed>

