Posts tagged 'opensource'



Building an Open Source J2EE Weblogger

I wrote this article for O'Reilly's OnJava.com over twenty years ago and it was published on April 17, 2002. Roller would not become Apache Roller until about five years later. Publishing this article changed my life and set my career on a new trajectory. I can't find it online anymore so to celebrate this anniversay, i'm going to publish it here on Roller.

As a Java developer, you should be aware of the tremendous wealth of open source development software that is available for your use -- even if you have no desire to release any of your own software as open source. In this article, I will introduce you to some of the most useful open source Java development tools by showing you how I used these tools to develop a complete database-driven Web application called Roller.

Roller fits into the relatively new category of software called webloggers: applications that make it easy for you to maintain a weblog, also known as a blog -- a public diary where you link to recent reading on the Web and comment on items of interest to you.

The Roller Web application allows you to maintain a Web site that consists of a weblog, an organized collection of favorite Web bookmarks, and a collection of favorite news feeds. You can define Web pages to display your weblog, bookmarks, and news feeds. By editing the HTML templates that define these pages, you have almost total control over the layout and appearance of these pages. Most importantly, you can do all of this without leaving the Roller Web application -- no programming is required.

I used over a dozen open source development tools to develop Roller, the most useful of which are listed in Table 1; however, this article focuses on just four tools: the XDoclet code generator, the Castor persistence framework, the Struts Servlet/JSP framework, and the Velocity code-generation engine. In this article I will describe the Roller application, its architecture, and specifically how I used XDoclet, Castor, Struts, and Velocity in its development.

Table 1: Open source tools used in Roller Development

Name

Description

Developer

Type of License*

Castor

Persistence framework

Exolab

Similar to BSD license

HSQL

Small but powerful Java database

Thomas Meuller

Similar to BSD license

Jakarta Ant

XML-driven Java build system

Apache

Apache Public License

Jakarta Commons

Collections, utilities

Apache

Apache Public License

Jakarta Struts

Servlet/JSP framework

Apache

Apache Public License

Jakarta Tomcat

Servlet/JSP Server

Apache

Apache Public License

Jakarta Velocity

Template-driven code generator

Apache

Apache Public License

Netbeans

Integrated Dev. Environment

 

Sun Public License

Xerces

XML parser

Apache

Apache Public License

XDoclet

Code generator

Dreambean

Similar to MIT License

* For more information on open source licenses see opensource.org

The Roller Application

Roller does not support all of the features of commercial weblogging software (such as Userland's Radio or Pyra Labs' Blogger products), but Roller does support what I consider the essential weblogging features. With Roller you can:

  • Maintain a weblog, with user-defined categories. You can write new weblog entries and edit entries that have already been posted. You can define a set of weblog categories and can assign weblog entries to different categories. This allows you to maintain several different weblogs, each covering a different topic.

  • Publish your weblog as an RSS news feed. Roller makes your weblog available as a standard Rich Site Summary (RSS) news feed so that readers can subscribe to and read your weblog without visiting your Roller site.

  • Maintain a collection of favorite bookmarks, organized by bookmark folders. You can define new bookmark folders and can add, delete, and edit the bookmarks within these folders. You can then display these bookmarks on one or more of your Roller site's pages. This allows you to do blogrolling -- displaying links to your favorite weblogs.

  • Maintain a collection of favorite RSS news feeds. This allows you to display headlines with links to news stories from your favorite news sources or weblogs.

  • Define a set of Web pages to display your weblog, bookmarks, and news feeds. Pages are defined using HTML templates with embedded macros for each type of data. For example, there is a $Bookmarks macro that will draw a portion of your bookmark collection on a Web page and a $WeblogCalendar macro that will draw a calendar view of your past weblog entries. These templates allow you almost complete control over the layout and look-and-feel of your Web pages.

There are two types of Roller users: readers and editors. Readers are simply anonymous visitors to the Roller Web site. Editors have user accounts and must log in by providing a user name and password. Editors have the ability to edit their weblog entries, bookmarks, newsfeeds, and page templates.

Figure 1 illustrates the Roller application by showing the Roller Web page navigation tree. The boxes represent Web pages and the arrows represent links between pages. The gray pages are the public pages that any visitor may access, the yellow pages are the login pages, and the red pages are the pages that only editors can access.

Diagram.
Figure 1: Roller Web Pages

Roller Architecture

Internally, Roller is divided into a presentation tier and a business tier, as recommended in Sun's J2EE Pattern Catalog. The presentation tier is responsible for Roller's user interface, and the business tier is responsible for Roller's application logic and the persistence of application data. Figure 2 provides an overview of the Roller architecture.

Diagram.
Figure 2: Roller Architecture

The presentation tier is implemented using the Model-View-Controller (MVC) pattern and the Struts MVC framework. The Model is an abstraction of the application logic and application data and is represented by a set of interfaces defined in the org.roller.model package. The View is implemented using Servlets, JSP pages, and Velocity page templates. The Controller is Struts, which is responsible for receiving incoming requests and dispatching them to the View. The implementation of the presentation tier is further discussed in the sections on Struts and Velocity.

The business tier implements the interfaces in the org.roller.model package, using the Castor JDO persistence framework. The business tier exchanges data with the presentation tier in the form of simple, lightweight JavaBeans known as Value Objects. Value Objects are yet another of the Sun J2EE patterns. Each Value Object maps to a table in the Roller database.

Figure 3 shows the Roller Value Objects, their properties, and the relationships between them. Each editor is represented by a User object. Each User has a Website object, which represents the editor's Web site and which has weblog entries, bookmark folders, newsfeeds, and page templates. The Website object also specifies the default page template of the Web site and which page template is used for rendering a day of weblog entries.

Diagram.
Figure 3: Roller Value Objects

The business tier uses Castor JDO to store and retrieve Value Objects to and from a JDBC-accessible database. Castor JDO is part of the larger Castor data-binding framework, which according to the Castor Web site is "the shortest path between Java objects, XML documents, SQL databases, and LDAP."

As a persistence framework, Castor JDO is similar to commercial object-relational mappers such as TopLink and Cocobase. Castor JDO fulfills a role similar to that of Sun's Java Data Objects, but Castor JDO is not an implementation of Sun's JDO specification (JSR-000012). Castor JDO allows you to define a mapping between Java classes and tables in a relational database. You can then issue queries using Castor's own Object Query Language (OQL) and receive the results as collections of Java objects.

Before you can use Castor JDO, you must provide a mapping file -- an XML file that maps each class to a database table and each class property to a field within a database table. Below is a portion of Roller's mapping file.

<mapping> 
<class name=org.roller.model.BookmarkData" identity="id"
    access="shared" key-generator="UUID" auto-complete="false">
    <map-to table="bookmark"/> 
    <cache-type type="count-limited"/>
    <field name="folderId" type="java.lang.String"></field>
    <field name="id" type="java.lang.String"></field>
    <field name="image" type="java.lang.String"></field>
    <field name="name" type="java.lang.String"></field>
    <field name="priority" type="java.lang.Integer"></field>
    <field name="url" type="java.lang.String"></field>
</class>
...
</mapping>

Once you provide Castor with a mapping file, retrieving a collection of objects from the database can be as simple as the code snippet shown below:

// Construct a new query and bind its parameters
String query = "SELECT p FROM BookmarkData p WHERE websiteId=$";
OQLQuery oql = db.getOQLQuery( query );
oql.bind( websiteId );

// Retrieve results and print each one
QueryResults results = oql.execute();
while ( results.hasMore() ) {
   BookmarkData bookmark = (BookmarkData)results.next();
   System.out.println( bookmark.toString() );
}

XDoclet

XDoclet is a code generator that is implemented as a Javadoc extension, a Doclet. To use XDoclet, you place special Javadoc tags in your Java source code. Based on these tags, XDoclet can generate additional Java code that supports your classes, mapping files that map your classes to database tables, and deployment descriptors that assist in deploying your classes.

XDoclet started out its life as EJBDoclet, a tool that allows you to implement an Enterprise JavaBean by writing just one source code file. Now, the XDoclet product includes two Doclets: EJBDoclet and WebDoclet. EJBDoclet is for generating EJB classes, value objects, and database mappings. WebDoclet is for generating all sorts of Servlet Web Application deployment descriptors, including web.xml files, Tag Library Descriptors, and Struts configuration files.

The Roller build process uses both EJBDoclet and WebDoclet, as shown in Figure 4. In Step 1, EJBDoclet is used to process a set of abstract classes of type javax.ejb.EntityBean -- one for each one of the Roller Value Objects. From these classes, EJBDoclet generates a Castor mapping file, the Roller Value Object classes, and a set of corresponding Struts form classes. In Step 2, WebDoclet is used to process a source directory that contains JSP tags, Servlet classes, and Struts classes. The output of the WebDoclet is the complete set of Roller Web Application deployment descriptors.

Diagram.
Figure 4: XDoclet and the Roller Build Process

Below is a simple example bean that shows the EJBDoclet tags necessary to create a Value Object. The @castor tags provide the information needed to generate the Castor mapping entries for the bean. The @ejb tags provide the information needed to generate the Value Object and a complete EJB entity bean (which Roller does not use).

/**
 * Represents a single URL in a user's favorite web-bookmarks collection.
 * @ejb:bean name="Bookmark" type="CMP" jndi-name="roller/Bookmark"
 * @ejb:data-object extends="org.roller.model.ValueObject"
 * @struts:form 
 * @castor:class name="bookmark" table="bookmark" xml="bookmark"
 *               id="id" key-generator="UUID"
*/ public abstract class BookmarkBean implements EntityBean { /** @ejb:interface-method * @ejb:transaction type="Required" */ public abstract void setData(org.roller.model.BookmarkData dataHolder); /** @ejb:interface-method */ public abstract org.roller.model.BookmarkData getData(); /** @castor:field set-method="setId" * @castor:field-xml node="attribute" * @castor:field-sql name="id" sql-dirty="check" dirty="true" * @ejb:interface-method * @ejb:pk-field * @ejb:persistent-field */ public abstract String getId(); /** @ejb:pk-field * @ejb:persistent-field */ public abstract void setId( String value ); ... }

Struts

The Roller presentation tier is implemented using Struts and Velocity. Struts is a Servlet application framework that is based on the MVC pattern. In a typical Struts application, the Model is a set of JavaBeans that hold the data to be presented in the View; the View is a set of JSP pages that render HTML; and the Controller is a Servlet and set of action classes that are registered to handle incoming requests.

Roller's Edit-Bookmark form provides a nice, simple example of how Struts works. There are four parts to the Edit-Bookmark form implementation: the edit-bookmark.jsp page, the BookmarkForm JavaBean class, the BookmarkFormAction action handler, and some entries in Roller's struts-config.xml file that tie the first three items together. So, let's introduce the players:

  • The edit-bookmark.jsp page looks just like an HTML page, except that it uses the Struts HTML form tags instead of standard HTML form tags. The Struts HTML form tags know how to find the BookmarkForm JavaBean and how to use its properties to populate the form with data.

  • The BookmarkForm class is a dumb JavaBean that just holds data -- it has the exact same properties as the Bookmark Value Object. As you may recall, the BookmarkForm class and all of its sibling form classes are generated by XDoclet. In Struts, form classes must extend org.apache.struts.action.ActionForm.

  • The BookmarkFormAction is essentially an action handler. It is registered (in the struts-config.xml file) to handle incoming requests that include the pattern /bookmark.do. In Struts, action classes must extend org.apache.struts.action.Action.

Figure 5 shows the sequence of events that occurs when a request for the Edit-Bookmark form comes into the system. Roller needs to respond to this request by creating an HTML form populated with data for the bookmark that is to be edited.

Diagram.
Figure 5: Incoming request for Edit-Bookmark page

Here are the steps in processing an incoming request for the Edit-Bookmark page:

  1. The Struts Controller Servlet receives a request for the Edit-Bookmark action. The Controller uses the URI of the request to look up the FormAction that should handle the request.

  2. The Struts Controller Servlet dispatches the request to the BookmarkFormAction.edit() method. Knowing that the user has requested the Edit-Bookmark page, the BookmarkFormAction looks for a request parameter that specifies the bookmark that is to be edited.

  3. The BookmarkFormAction calls the BookmarkManager to retrieve the bookmark information that is to be edited.

  4. The BookmarkFormAction creates the BookmarkForm bean and adds that bean to the request's attributes so that it can be accessed by the JSP page.

  5. The BookmarkFormAction finally forwards the request to edit-bookmark.jsp so that the page may be rendered.

  6. The Struts form tags on the edit-bookmark.jsp page reads data from the BookmarkForm bean and uses that data to populate the Edit-Bookmark form. After that, the HTML page is returned to the user's browser for display.

Figure 6 shows the sequence of events that occurs when the request that contains posted data from the Edit-Bookmark page comes into the system. Roller needs to take the incoming form data and use it to update the bookmark that is stored in the data store managed by the business tier.

Diagram.
Figure 6: Request with data posted from Edit-Bookmark page

Here are the steps in processing a request with data from a posted Edit-Bookmark page:

  1. The Struts Controller Servlet receives a request for the Update-Bookmark action. The Struts Controller determines which action should handle the request and which form bean should receive the data from the incoming form post.

  2. The Struts Controller Servlet populates the BookmarkForm bean with data from the incoming request.

  3. The Controller calls the BookmarkFormAction and passes in the form bean.

  4. The BookmarkFormAction retrieves the data from the BookmarkForm bean.

  5. The action calls upon the BookmarkManager to store the updated bookmark information.

Velocity

While JSP pages work well for the Roller editor pages, which rarely change, JSP does not work so well for the user pages. Weblog authors are not programmers, and they cannot be required to learn JSP and Java programming just to customize their weblog and associated Web pages. Furthermore, allowing Roller users to add new JSP pages, and thus new Java code, to the Roller application at runtime is a security risk.

Screen shot.
Figure 7: Velocity-generated public page

The best solution to the user pages problem is Velocity. Velocity is a general purpose template-based code-generation engine. That may sound complicated, but from the user's point of view, it is simple and easy-to-use. For example, the weblog page shown in Figure 7 is generated by a simple Velocity template. This template is shown below:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
;<head>
<title>$macros.showWebsiteTitle()</title>     
<style type="text/css">$macros.includePage("_css")</style>
</head>
;<body> 
<table cellpadding="5" cellspacing="15" 
border="0" align="center" width="95%"> <tr> <td width="20%" valign="top" bgcolor="#ffffff"> $macros.showNavBar(true)<br> $macros.showEditorNavBar(true)<br> $macros.showBookmarks("Blogrolling",true)<br> $macros.showBookmarks("News",true) </td> <td width="60%" valign="top" bgcolor="#ffffff"> <h2>$macros.showWebsiteTitle()</h2> $macros.showWeblogCategoryChooser()<br> $macros.showWeblogEntries() </td> <td valign="top" bgcolor="#ffffff" width="20%"> $macros.showWeblogCalendar()<br> $macros.showRSSBadge() </td> </tr> </table> </body> </html>

The items that start with $ are Velocity expressions, most of which result in calls to JSP tags that have been specially designed to work with Velocity. For example, the $macros.showWeblogCategoryChooser() expression results in the generation of the navigation bar at the top of the page -- the one that reads "All | Technology | News | Entertainment." The navigation bar is implemented in a custom JSP tag class named org.roller.presentation.tags.NavigationTag, which is also used in the JSP-based Roller editor pages.

Each user can define any number of pages, and since these pages are simply HTML pages, they can be customized using Front Page or any other HTML editor. The user just has to put the Velocity expressions in the right place. Below is a list of some of the Velocity expressions that are available for use in user-defined Roller Web pages.

Macro

Emits HTML for:

$macros.showNavBar()

Navigation bar, with a link to each one of the user's user-defined pages

$macros.showEditorNavBar()

Editor navigation bar, with links to the edit-bookmarks,edit-newsfeeds, edit-weblog, and edit-website pages

$macros.showBookmarks()

Entire bookmark collection in a multi-column table

$macros.showNewsfeeds()

Current headlines and story descriptions for the user's RSS newsfeeds

$macros.showWeblogEntries()

The most recent weblog entries

$macros.showWeblogCalendar()

A weblog calendar, with a link for each day on which there is a weblog entry

Conclusion

In this article, I have described four open source Java development tools and how these tools can be used together to develop a fairly sophisticated Web application. I hope I have given you a good idea of the power and flexibility of these tools.

Although I have not mentioned any problems with the open source tools that I have discussed, I did run into a number of bugs. I was able to find work-arounds and fixes for these bugs, but it was not always easy. I had to spend some time browsing mailing-lists, searching with Google, and, in one case, downloading the latest source for a product and building it myself. Formal technical support is not available for many open source tools, so keep in mind that you may have to solve your own problems.

In closing, I would like to thank the many developers and other contributors that made possible the open source Java development tools that I used in the development of Roller. The tools are great and they just keep getting better.

Resources

Weblogging

Castor

Struts

Velocity

XDoclet

Originally published here: http://onjava.com/onjava/2002/04/17/wblogosj2ee.html


Apache Shiro for authentication in Roller

Shiro logo

This is the third of my 2014 side projects that I'm sharing and one that involves the Apache Roller blog server and the Apache Shiro security framework. You might find this interesting if you're considering using Shiro for authentication and authorization, or if your interested in how security works in Apache Roller.

Inspired by my work with Ember.js 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'd need to add a comprehensive REST API to Roller, and I'd need a way to implement secrity for the new API. I've enjoyed working with Apache Shiro, so I decided that a good first step would be to figure out how to use Apache Shiro in Roller for Roller's existing web interface.

Working over the winter break I was able to replace Roller's existing Spring security implementation with Shiro and remove all Spring dependencies from my Rollarcus fork of Roller. Below I'll describe what I had to do get Shiro working for Form-base Authentication in Roller.

Creating a Shiro Authorizing Realm

The first step in hooking Shiro into Roller is to implement a Shiro interface called ShiroAuthorizingRealm. This interface enables Shiro to do username and password checks for users when they attempt to login, and to get the user's roles.

Below is the first part of the class, which includes the doGetAuthenticationInfo() method, which returns the AuthenticationInfo for a user specified by an AuthenticationToken that includes the user's username. In other words, this method allows Shiro to look-up a user by providing a username and get back the user's (hashed) password, so that Shiro can validate a user's username and password.

ShiroAuthorizingRealm.java (link)
public class ShiroAuthorizingRealm extends AuthorizingRealm {

    public ShiroAuthorizingRealm(){
        setName("ShiroAuthorizingRealm");
        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(
                "Error looking up user " + token.getUsername(), ex);
        }

        if (user != null) {
            return new SimpleAuthenticationInfo( 
                user.getUserName(), user.getPassword(), getName());

        } else {
            throw new AuthenticationException(
                "Username not found: " + token.getUsername());
        }
    }

In the code above you can see how we pull the username out of the authToken provided by Shiro and we call a method, loadUserByUserName(), which uses Roller's Java API to load a Roller user object specified by name.

The next method of interest is doGetAuthorizationInfo(), which allows Shiro to look-up a user's Role. This allows Shiro to detmerine if the user is a Roller admin user or a blog editor.

ShiroAuthorizingRealm.java (continued)

    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("Error looking up user " + 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(
                    "Error looking up roles for user " + userName, ex);
            }
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            for ( String role : roles ) {
                info.addRole( role );
            }
            log.debug("Returning " + roles.size() 
                + " roles for user " + userName + " roles= " + roles);
            return info;

        } else {
            throw new RuntimeException("Username not found: " + userName);
        }
    }

In the code above you can see that we use the loadUserByUsername() too look-up a user by username, then we use Roller's Java API to get the user's roles. We add those roles to an instance of the Shiro class SimpleAuthorizationInfo and return it to Shir.

Creating a Shiro Authorizing Filter

Now that we've implementated a realm, we'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 RolesAuthorizationFilter, which is close to what we need but not exactly right for Roller. I had to extend Shiro's roles filter so that we can allow a user who has any (not all) of the required roles for a resource.

RollerRolesAuthorizationFilter.java (link)
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;
    }
}

Configuring Shiro for Roller

Now that we'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.

shiro.ini (link)
[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]

In the configuration file above, you see how we hook in the new ShiroAuthorizingRealm on line 3. The next couple lines are boiler-plate code to hook in Shiro's caching mechanism and then, on line 9, we configure an authentication method called authc, which is configured to use Shiro's Form Authentication feature. And, on line 13, we hook in our new RollerRolesAuthorizationFilter.

Next, we tell Shiro that the login page for Roller is /roller-ui/login.rol and which page to direct a user to on a successful login, /roller-ui/menu.rol, 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.

Wrapping up...

That's all there is to the story of Roller and Shiro so far. I was able to get Roller'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 Rollarcus fork of Roller. You can get the code from the shiro_not_spring branch. Pull requests are quite welcome as are suggestions for improvement. Please let me know if you see anything wrong in the above code.

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.


Talking Usergrid at ApacheCon 2014

ApacheCon 2014

I've been working at Apigee since September 2013 and one of the things I love most about my new job is the fact that I'm actively contributing to open source again.

I'm working on Apache Usergrid (incubating), an open source Backend-As-A-Service (BaaS) that's built on the Apache Cassandra database system. Apigee uses Usergrid as part of Apigee Edge (see the Build Apps part of the docs).

Apigee contributed code for Usergrid to the Apache Software Foundation 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.

One on the most important parts of building an open source community is making it easy for people to contribute and and that's why I submitted a talk to the ApacheCon US 2014 conference (April 7-9 in Denver, CO) titled How to Contribute to Usergrid.

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.

Here's the outline I have so far:

How to Contribute to Apache Usergrid

  • Motivation
    • Why would anybody want to contribute to Usergrid?
  • First steps
    • The basics
    • Getting signed up
  • Contributing to the Stack
    • Understanding the architecture & code base
    • Building the code. Making and testing changes
    • Running Usergrid locally via launcher & via Tomcat
  • Contributing to the Portal
    • Understanding the architecture & code base
    • Building the code. Making and testing changes
    • Running the portal locally via node.js
  • Contributing to the SDKs
    • Understanding the architecture & code base
    • Building the code. Making and testing changes
  • Contributor workflow: how to get your code into Usergrid
    • For quickie drive-by code contributions
    • For more substantial code contributions
    • For documentation & website changes
  • Contributing Docs and Website changes
    • Website, wiki and GitHub pages
    • How to build the website and docs
  • Roadmap
    • First release
    • New Core Persistence system
    • The two-dot-o branch
    • Other ideas

I'm in the process of writing this talk now so suggestions and other feedback are most welcome.


GSOC 2011: Mobile-enabled themes for Roller

I'm going to break blog silence now to tell you about Apache Roller and Google Summer of Code 2011, which just wrapped up about a week ago.

GSOC logo

This year we were very fortunate to get a another highly motivated and smart student, Shelan Perera, and an good proposal as well: Mobile-enabled Templates. Over the summer Shelan designed and implemented a new feature for the Roller blog server, one that enables theme authors to provide an alternative "mobile" template for each page template in a Roller blog theme. You can see a screenshot of the new Edit Template page in Shelan's blog How to change template codes in Roller.

Now, when a page request comes into Roller, Shelan's code determines if it's from a mobile device and, if it is, switches to a mobile template, if one is available. There's also an easy way for template authors to create a button to allow users to switch to the "Standard" site instead of the mobile version. The screenshot on the right, of Roller with a mobile theme comes from Shelan's most recent blog.

screenshot of a mobile Roller theme

It was an honor to act as mentor for this project, and fun talking to Shelan via Skype most Fridays. I'm looking forward to getting this on my blog, and getting this cool new feature into an Apache Roller 5.1 release sometime soon. Thanks, Shelan! And, thanks to Google for running the most excellent Summer of Code program.


Apache Roller 5.0 released

$entry.displayContent($url.entry($entry.anchor))

Congrats to Webmink and Forgerock

Congrats to Simon Phipps on what sounds like a great new job at ForgeRock and on his new column in ComputerWorld.UK.

One of the key benefits to customers of the source code becoming open source is that, in the event a product is discontinued by its owner, a group of people from the community can simply pick up the source code and keep on maintaining and improving it. That's a radical change from proprietary products, which can be killed stone dead with no appeal. With open source, the company may fold but the community carries on.

That's all fine in theory, but does it actually work? I intend to find out. Starting this week, I'm joining ForgeRock as chief strategy officer.

Read More

Oracle: please follow through on Project SocialSite

One year ago on this day I wrote that Sun Microsystems is willing to contribute Project SocialSite" to the Apache Software Foundation. My contacts at Sun told me it was OK to make that announcement because a VP approved. One year later, we have established Apache SocialSite (incubating) project, setup user accounts, put up a status page and setup source code control but we still have no code from Sun.

Since March 2009 I've been exchanging emails with my helpful contacts at Sun and trying to help them move forward with the contribution, but because of the ongoing Oracle/Sun merger things have moved incredibly slowly. Finally in late December 2009, my Sun contacts had permission to actually release the code to Apache, but there was a problem.

When Sun said that they were willing to contribute the SocialSite code to Apache, I figured that they would do so using the standard Software Grant agreement that was used for Roller and all other projects entering Apache via the Incubator. Unfortunately, the Sun lawyers did not want to use the standard Software Grant agreement and Apache did and does not want to devise a new legal agreement just to accommodate Sun. That's where we stand today. Sun committed to contributing SocialSite to Apache and now we're waiting for Oracle/Sun to follow through on that commitment.

Meanwhile, others have been making some progress with SocialSite. A major sports brand has launched a SocialSite based network with a million-plus users. A couple of developers have rewritten the build script to use Maven, others have "ported" to JBoss and there is still interest in and a need for what was Sun's Project SocialSite. Neither effort has contributed code back to SocialSite-proper and because of legal concerns are waiting for the main code to appear at Apache.

fish1 fish2 fish3

SocialSite is a small project and it will not survive for much longer with resources spread across multiple sites and a community working separately. So, I'm asking again and publicly: Oracle, please follow through on your commitment and grant the Project SocialSite codebase to Apache.


Roller Beginner's Guide available

photo of beginner's guide to Apache Roller 4.0

I blogged about Alfonso Romero's Apache Roller 4.0 Beginner's Guide book before. It's a great resource for folks who want to get the most out of their Apache Roller-based blogs, and not just beginners. As you can see in the photo on the right, I've got my copy. You can get yours directly from Pakt publishing:

Buy a copy of Beginner's Guide to Apache Roller 4.0

To publicize the book, Pakt publishing has been publishing some useful excerpts and even a complete sample chapter online. Here's summary of the excerpts so far:

If you've been following Roller development you know that Roller 5.0 is on the way. Most of the changes in Roller 5.0 are "under the hood" so 5.0 won't make Alfonso's book obsolete. Except for a couple of pages in Chapter 5 "Spicing Up Your Blog" that need updated screenshots, I believe everything in the book applies to Roller 5.0 as well.


Month of blogging

Crammed into one post...

After a month of blog neglect, my automatic Latest Links from my Delicious.com account started to pile up. Back in the glory days of this blog, I blogged about things instead just saving links or tweeting about them. I realized that, by adding some commentary/opinion for each, I could turn a month's worth of links into a month's worth of blog posts and thus gain total absolution for my sin of going a full month without a post. So that's what I did.  [Read More]

Media Blogging for Roller

For the past five months I've had the pleasure of mentoring two San Jose State Univ. graduate students, Ganesh Mathrubootham and Tanuja Varkanthe, who are working on a project for classes CMP 295A and B. They picked one of the projects that I first proposed for Google Summer of Code and then for Glassfish's student outreach program, Media Blogging for Apache Roller. It's turned out to be a major project and the central new feature in the upcoming Roller 5.0 release. [Read More]

ROME 1.0 RC2 on the way

Nick's Twitter icon

Good news for ROME fans. Nick Lothian picked up the puck and is galloping towards the finish line (sorry, I'm terrible at sports analogies).

Nick Lothian on ROME dev:

I've gone and built some preview jars for the upcoming ROME 1.0RC2, ROME Fetcher 1.0RC2 and Modules 0.3 release.

Those jars can be found here: https://rome.dev.java.net/servlets/ProjectDoc...

I've created source and javadoc jars as well as the normal jars - the idea being that I'll get them uploaded to some maven repository.

If you have some spare time, please take a look at these and test them and let me know of any problems. Assuming there are no big issues found I'd like to do a proper release in a couple of days.

Guess that means I should test Propono with RC2.


Atom news: Apache Abdera graduates

Atom logo

Congratulations to the Apache Abdera team, who've just graduated to full Apache top level project status. The don't have the new site at abdera.apache.org up yet and they're still not quite at 1.0 yet, but this is a major milestone. They've got the best Atom format and protocol toolkit around, in my opinion.

via Garett and James.


Open Source Days 2008 - Copenhagen

My talk went pretty well yesterday and I'm definitely enjoying both the conference, which is still in progress, and my stay in Copenhagen. I'll post more photos later, but for now here is a shot of the conference setup at ITU Copenhagen.

Open Source Days 2008 - Copenhagen

Roller and SocialSite at Open Source Days 2008

Open Source Days 2008 logo

I'm happy to report that I'll be traveling to Copenhagen, Denmark to talk about Roller and Project SocialSite at the Open Source Days 2008 conference on Oct. 3-4 this year. I'm going to tell the story of Roller and lessons learned along the way and then talk about blogging in the age of social networks and how to social-enable Roller with the SocialSite widgets. The session is called titled The once and future Roller.

Roller status

feather logo

If you want the lowdown on what's going on with Roller community health, ongoing work and upcoming releases then check out the Apache Roller August 2008 Board Report.


Latest Links - Open Source


Project SocialSite opens up!

My teammates and I have started a new blog over at blogs.sun.com to cover Project SocialSite and to break the big news: we're open!

We are very pleased to announce that source code is now available for Project SocialSite (under a CDDL/GPL license) and the project is now operating as an open source project following the Glassfish governance policy. We're working in the open and welcome contributors of all stripes. Read more...

JSPWiki vs. XWiki

via Jim Grisanzio: Chris Phelan has done evaluations of JSPWiki and XWiki for use on the OpenSolaris.org site. Based on his 32 requirements, XWiki came out on top.

On balance, XWiki wins by virtue of having better support for management, searching, page taxonomies, virtual servers, content export and language translation/localization support.

JSPWiki has slightly better support for identifying orphaned pages and accesskey support (XWiki 1.4 will have support for access keys).

Confluence was not considered because requirement #0 is "the software must be free and open source," which seems like a reasonable request when selecting software for an open source community site.


Latest Links - misc

It's time to catch up on blogging and I'm going to start by going through my backlog of links and adding some commentary, but not in this post; these are miscellaneous links that don't fit nicely into my other posts.


Latest Links: open source, social networking and etc.

Main | Next page »