ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Introducing [fleXive] - A Complementary Approach to Java EE 5 Web Development
Pages: 1, 2, 3, 4

Since we can hardly rely on the users of our application executing this code snippet for every installation, we place the script file in the resources/scripts/runonce folder. This way, it will be run exactly once for each database this application runs on (there is also a startup folder for scripts that are executed on every application startup).



The backend application offers a powerful generic editor for arbitrary [fleXive] content types. Depending on the actual data structure, the editor offers buttons to create or remove input fields, as well as repositioning them (which is useful for "ordered" data structures, e.g., a news article consisting of multiple paragraphs and images).

To create new content -- as a first instance of the newly created type -- click on the Content Tree's tab on the left, right-click on the tree's root node, and select "Create content..." to get a list of all registered types. A manufacturer form, generated from the type definition above, looks like this:

manufacturer
Figure 3. Creating a new manufacturer content instance

The product editor offers a field to reference a manufacturer, as well as the nested variant group. You can add more variants by clicking on the image on the upper left corner of the box.

product
Figure 4. Creating a new product content instance

You can go on and create some product descriptions and manufacturers. Notice how new instances pop up in the "Content Tree" on the left side. You can even create your own hierarchy, for example by creating folders for product types. You can also opt to not use the "Content Tree" at all, it's just a helpful way of organizing data objects. To search for existing contents of a type using the context menu in the "Structure" tab on the left side.

Writing a Frontend - Meet the [fleXive] API

While the generic input forms are handy for managing your data without having to manually code editors, you also want a web page to show your data to the customer. [fleXive] provides a component toolkit based on JSF that makes it almost trivial to render [fleXive] contents in web applications. In this first tutorial, we'll implement a basic, read-only view of all our products that can easily be customized and extended in all the ways JSF has to offer.

Content Queries and Result Sets

The main page of our frontend displays a list of all products. To retrieve all products, we issue a query using [fleXive]'s custom search engine and render the result using a plain JSF datatable. Queries can be issued in a SQL-like dialect or using a Java builder class. We fetch the results in a JSF managed bean, which can then be accessed via JSF EL (i.e., #{productBean.products}). Since this class is part of the web application, we place it in the src/java/war folder. The package structure is up to you, we chose com.flexive.example.war.

public class ProductBean {
  private DataModel products;

  public DataModel getProducts() throws FxApplicationException {
    if (products == null) {
      final FxResultSet result =
               new SqlQueryBuilder()
               .select("@pk", "product/name", "product/price",
                       "product/variant/articlenumber")
               .filterVersion(VersionFilter.LIVE)
               .type("product")
               .orderBy("product/name", SortDirection.ASCENDING)
               .getResult();
      products = new FxResultSetDataModel(result);
    }
    return products;
  }
}

You could also issue the above query using the FxSQL query language, using the search engine EJB:

EJBLookup.getSearchEngine().search(
    "SELECT co.@pk, co.product/name, co.product/price, "+
    " co.product/variant/articlenumber " +
    "FROM content co " +
    "FILTER co.version=LIVE " +
    "WHERE (co.typedef = 7) " +
    "ORDER BY co.product/name",
    0, 1000, null)

Next we need a frontend page to render our products. [fleXive] uses Facelets for building JSF pages, which allows us to use a very clean XHTML syntax. All frontend pages are stored in the web directory, while component templates go to resources/templates. Since we'll need the product table on more than one page, we define a template in resources/templates/productTable.xhtml We also have to register the template in resources/META-INF/products.taglib.xml. The actual template is plain JSF: the datamodel returns a linear list of all found products, which are rendered using a JSF datatable.

<h:dataTable var="row" value="#{productBean.products}"
                     styleClass="products">
  <h:column>
    <fx:thumbnail pk="#{row[0]}"/>
  </h:column>
  <h:column>
    <f:facet name="header">
      #{fxMessageBean['products.productTable.column.product']}
    </f:facet>
    <fx:resultValue value="#{row[1]}"/>
  </h:column>
  <h:column>
    <f:facet name="header">
      #{fxMessageBean['products.productTable.column.price']}
    </f:facet>
      <fx:resultValue value="#{row[2]}"/> EUR
  </h:column>
  <h:column>
    <h:commandLink action="productDetails">
      <f:setPropertyActionListener value="#{row[0]}"
                                  target="#{productBean.pk}"/>
        #{fxMessageBean['products.productTable.button.details']}
      </h:commandLink>
  </h:column>
</h:dataTable>

The resulting HTML output looks like this:

product listing
Figure 5. Generated product list

Pages: 1, 2, 3, 4

Next Pagearrow