Tuesday May 11, 2010

TOTD #135: JSF2 Composite Components using NetBeans IDE - lightweight Java EE 6

NetBeans IDE provide comprehensive feature set to build applications using Java Server Faces 2 (JSR 314). This Tip Of The Day (TOTD) explains how to create JSF composite components using wizards provided by the NetBeans IDE.

The JSF2 specification, section 3.6 defines composite components as:

A tree of "UIComponent" instances, rooted at a top level component, that can be thought of and used as a single component in a view. The component hierarchy of this subtree is described in the composite component defining page.

This definition is good from the specification perspective but can help with some layman explanation. Essentially, a composite component is what it says - a composition of two or more components such that it behaves like a single component. For example, consider four components in a panel grid where 2 components are "h:outputText" to display prompts and other 2 are "h:inputText" to receive input from the user. The composite components allow all of these components (1 panel grid + 2 "h:inputText" + 2 "h:outputText") packaged as a single component.

Resource Handling and Facelets, both features newly introduced in the JSF2 specification, makes the creation of composite component much easier. The Resource Handling defines a standard location for bundling resources in a web application and Facelets defines a cleaner templating language that enables composition. In technical terms:

A composite component is any Facelet markup file that resides inside of a resource library.

Lets create a simple Web application using JSF 2 that accepts a username/password and displays it in a new page. The application is first created using the traditional "h:inputText" and "h:outputText" elements and is then converted to use a composite component.

Before we dig into composite component creation using JSF2, here are the steps listed to create one using JSF 1.2:

  1. Implement UIComponent subclass
  2. Markup rendering code in Renderer
  3. Register your component and renderer in faces-config.xml
  4. Implement your JSP tag
  5. And the TLD

There is Java code involved, sub-classing from JSF classes, deployment descriptor editing in "faces-config.xml", declaring TLDs and then implementing the JSP tag. Creating a composite component in JSF 1.2 was quite a chore and spread all over. There are lots of files

With that background, lets see what it takes us to create a composite component using JSF2.

The CDI backing bean for the application looks like:

package server;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named("simplebean")
@RequestScoped
public class SimpleBean {
    String name;
    String password;

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

The "index.xhtml" Facelet markup file looks like:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:h="http://java.sun.com/jsf/html">
  <h:head>
    <title>Enter Name &amp; Password</title>
  </h:head>
  <h:body>
    <h1>Enter Name &amp; Password</h1>
    <h:form>
      <h:panelGrid columns="2">
        <h:outputText value="Name:"/>
        <h:inputText value="#{simplebean.name}" title="name" 
                     id="name" required="true"/>
        <h:outputText value="Password:"/>
        <h:inputText value="#{simplebean.password}" title="password" 
                     id="password" required="true"/>
      </h:panelGrid>
      <h:commandButton action="show" value="submit"/>
    </h:form>
  </h:body>
</html>


And the "show.xhtml" Facelet markup looks like:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html">
  <h:head>
    <title>Show Name &amp; Password</title>
  </h:head>
  <h:body>
    <h1>Show Name &amp; Password</h1>
    <h:panelGrid columns="2">
      <h:outputText value="Name:"/>
      <h:outputText value="#{simplebean.name}" />
      <h:outputText value="Password:"/>
      <h:outputText value="#{simplebean.password}" />
    </h:panelGrid>
  </h:body>
</html>



Now select the <panelGrid> fragment in "index.xhtml" as shown below:

Right-click and select "Convert To Composite Component ..." and specify the values as given in the wizard below:

Note, most of the values are default and only the "File Name:" is changed. After clicking on "Finish" in the wizard, the updated page looks like:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:ez="http://java.sun.com/jsf/composite/ezcomp">
  <h:head>
    <title>Enter Name &amp; Password</title>
  </h:head>
  <h:body>
    <h1>Enter Name &amp; Password</h1>
    <h:form>
      <ez:username-password/>
      <h:commandButton action="show" value="submit"/>
    </h:form>
  </h:body>
</html>

The namspace/prefix "http://java.sun.com/jsf/composite/ezcomp" is added to the markup page. <ez:username-password> is the composite component used instead of those multiple components. The namespace prefix, "ez", and the tag name, "username-password", are chosen based upon the values entered in the wizard.

The JSF 2 specification, section 3.6.1.4 defines that:

The occurrence of the string “http://java.sun.com/jsf/composite/” in a Facelet XML namespace declaration means that whatever follows that last “/” is taken to be the name of a resource library.

The resource library location is relative to the Facelet markup file that is using it. So in our case, all the code is rightly encapsulated in the "resources/ezcomp/username-password.xhtml" file as:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:cc="http://java.sun.com/jsf/composite"
     xmlns:h="http://java.sun.com/jsf/html">

    <!-- INTERFACE -->
    <cc:interface>
    </cc:interface>

    <!-- IMPLEMENTATION -->
    <cc:implementation>
      <h:panelGrid columns="2">
        <h:outputText value="Name:"/>
        <h:inputText value="#{simplebean.name}" title="name"
                   id="name" required="true"/>
        <h:outputText value="Password:"/>
        <h:inputText value="#{simplebean.password}" title="password"
                   id="password" required="true"/>
      </h:panelGrid>
 </cc:implementation>
</html>

Notice, the composite component name matches the Facelet markup file name. The markup file lives in "resources/ezcomp" directory as indicated by the namespace value.

<cc:interface> defines metadata that describe the characteristics of component, such as supported attributes, facets, and attach points for event listeners. <cc:implementation> contains the markup substituted for the composite component.

The "index.xhtml" page is using the composite component and is conveniently called the using page. Similarly the "username-password.xhtml" page is defining the composite component and is conveniently called the defining page. In short, creating composite components in JSF2 requires the following steps:

  1. Move the required tags to a separate Facelet markup file, "defining page", in the "resources" directory
  2. Declare the namespace/prefix derived from "http://java.sun.com/jsf/composite" and the directory name
  3. Refer the composite component in the "using page".

Much simpler and cleaner than JSF 1.2. Are you using JSF 2 composite components ?

The entire source code used in this blog can be downloaded here.

JSF 2 implementation is bundled with GlassFish Server Open Source Edition, try it today!

Technorati: totd glassfish v3 netbeans jsf2 javaee composite components ajax

Thursday Feb 11, 2010

TOTD #123: f:ajax, Bean Validation for JSF, CDI for JSF and JPA 2.0 Criteria API - all in one Java EE 6 sample application

Taking TOTD #120 forward, we'll add the following features to our application:

  • Add database access using Java Persistence API 2.0
  • Show type-safe Criteria API from JPA 2.0
  • Use Context & Dependency Injection for JSF managed beans
  • Add Ajax effects from Java Server Faces 2.0
  • Add Bean Validation to the JSF managed bean

Lets get started!

  1. Use the Maven project created in TOTD #120 and update the directory such that it looks like:
    src
    src/main
    src/main/java
    src/main/java/org
    src/main/java/org/glassfish
    src/main/java/org/glassfish/samples
    src/main/java/org/glassfish/samples/SakilaBean.java
    src/main/java/org/glassfish/samples/SimpleBean.java
    src/main/java/org/glassfish/samples/SimpleEJB.java
    src/main/java/org/glassfish/samples/SimpleServlet.java
    src/main/webapp
    src/main/webapp/index.jsp
    src/main/webapp/index.xhtml
    src/main/webapp/sakila.xhtml
    src/main/webapp/show.xhtml
    src/main/webapp/WEB-INF
    src/main/webapp/WEB-INF/beans.xml
    src/main/webapp/WEB-INF/web.xml
    
    
    The key differences are:

    1. "beans.xml" is an empty file to enable Context & Dependency Injection bean discovery.
    2. The JPA Persistence Unit is copied and installed in local Maven repository as explained in TOTD #122.
    3. "web.xml" is added to bootstrap the Java Server Faces runtime. This is required because "@ManagedBean" annotation on "SimpleBean" class is now changed to "@javax.inject.Named". The JSF runtime is automatically registered and booted if any bean in the webapp is annotated with "@ManagedBean" or one of the JSF common classes (such as Converter, Validator, or Renderer) is implemented or extended. If none of these "hints" are available in the application, and it's required, then it needs to enabled explicitly.

Here are the updated files, changes are highlighted in bold and explained after each fragment:

index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtm
l1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
 xmlns:ui="http://java.sun.com/jsf/facelets"
 xmlns:h="http://java.sun.com/jsf/html">
 <h:head>
 <title>Enter Name &amp; Age</title>
 </h:head>
 <h:body>
 <h1>Enter Name &amp; Age</h1>
<h:form>
 <h:panelGrid columns="3">
 <h:outputText value="Name:"/>
 <h:inputText value="#{simplebean.name}" title="name" id="name" required="true"/>
 <h:message for="name" style="color: red"/>
 <h:outputText value="Age:"/>
 <h:inputText value="#{simplebean.age}" title="age" id="age" required="true"/>
 <h:message for="age" style="color: red"/>
 </h:panelGrid>
 <h:commandButton action="show" value="submit"/>
 </h:form>
 </h:body>
</html>

Changed the panelGrid from "2" columns to "3". This allows for any validation messages to be displayed right next to the source. Also added "<h:message .../>" to display the validation messages.



SimpleBean.java

package org.glassfish.samples;

import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.validation.constraints.Min;

@Named("simplebean")
@RequestScoped
public class SimpleBean {
 @NotNull
 @Size(min=2, message="Name must be at least 2 characters")
 private String name;

 @NotNull
 @Min(5)
 private int age;

 public String getName() { return name; }
 public void setName(String name) { this.name = name; }

 public int getAge() { return age; }
 public void setAge(int age) { this.age = age; }
}

The changes to the above code are listed below:

  • Replaced "@ManagedBean" with "@Named" annotation defined in JSR 330 and used by CDI.
  • Using constraints defined by Bean Validation APIs (JSR 303) to check for
    • Both bean properties to be non-null
    • Name to be at least 2 characters
    • A minimum age of 5
    • There are several other pre-defined constraints in "javax.validation.constraints" package and new constraints can be easily defined as well.

SakilaBean.java

package org.glassfish.samples;

import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.faces.event.ActionEvent;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceUnit;
import javax.persistence.EntityManagerFactory;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import sakila.Actor;

@Named("sakilabean")
@RequestScoped
public class SakilaBean {
 @PersistenceUnit(unitName="SakilaPU")
 EntityManagerFactory emf;

 private List<Actor> actors;
 private int length;
 private int totalActors;

 // getters & setters
 public List<Actor> getActors() { return actors; }
 public void setActors(List<Actor> actors) { this.actors = actors; }
 public int getLength() { return length; }
 public void setLength(int length) { this.length = length; }
 public int getTotalActors() { return totalActors; }
 public void setTotalActors(int totalActors) { this.totalActors = totalActors; }

 public void findActors(ActionEvent evt) {
   EntityManager em = emf.createEntityManager();

   CriteriaBuilder cb = emf.getCriteriaBuilder();
   CriteriaQuery<Actor> criteria = cb.createQuery(Actor.class);

   // FROM clause
   Root<Actor> actor = criteria.from(Actor.class);

   // SELECT clause
   criteria.select(actor);

   // WHERE clause
   criteria.where(cb.greaterThan(
     cb.length(actor.get("firstName").as(String.class)), length));

   // FIRE
   actors = em.createQuery(criteria).getResultList();
   totalActors = actors.size();
 }
}

The key points:

  • This is a CDI bean marked by @Named and used in the JSF view (shown next), with the name "sakilabean"
  • EntityManagerFactory is injected using @PersistenceUnit
  • "findActors" method builds the query using Criteria API. Returns actors' names limited by the number of characters in their first name.
  • Queries "Actor" table from the database and set bean properties "actors" and "totalActors".
  • Uses "length" bean property (set from the JSF view) to restrict the number of characters in the name.

sakila.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtm
l1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html">
  <h:head>
    <title>Sakila - Actors Listing</title>
  </h:head>
  <h:body>
    <h1>Sakila - Actors Listing</h1>
    <h:form>
    <h:outputText value="Show actors with first name's length &lt;"/>
    <h:inputText value="#{sakilabean.length}" id="length" required="true" size="5"/>
    <h:commandButton actionListener="#{sakilabean.findActors}" value="submit">
      <f:ajax execute="length" render="actorTable totalActors"/>
    </h:commandButton><br/>
     Total actors found: <h:outputText value="#{sakilabean.totalActors}" id="totalActors"/><p/>
     <h:dataTable var="actor" value="#{sakilabean.actors}" border="1" id="actorTable">
       <h:column><h:outputText value="#{actor.firstName}"/>, <h:outputText value="#{actor.lastName}"/></h:column>
     </h:dataTable>
   </h:form>
 </h:body>
</html>

Key points:

  • This JSF view shows a form that accepts a number used for restricting the length of actors' first name. The value of this attribute is bound to "length" property of the underlying bean.
  • Command Button is tied to a JSF Action Listener which is then bound to "findActors" method in the bean. This method executes the JPA query explained above.
  • "f:ajax" is a newly introduced tag in JSF 2.0 and means an Ajax request is performed on the "onClick" event of the rendered button, "findActors" method in the bean in this case. The tag also specifies other tags in the page, "actorTable" and "totalActors" in this case, that needs to be rendered after the request is completed. The input parameter to the Ajax request is specified using "execute" attribute. Read more about this tag here or section 10.4.1.1 of the JSF 2 specification.

Package and deploy the application as:

mvn clean package
./bin/asadmin deploy --force=true ~/samples/javaee6/simplewebapp/target/simplewebapp-1.0-SNAPSHOT.war

The application is now accessible at "http://localhost:8080/simplewebapp-1.0-SNAPSHOT/sakila.jsf" and looks like:

Enter a value of "4" in the text box and hit "Submit":

Only the HTML table of names and the total count of actors is refreshed showcasing partial page refresh.

Now enter a value of "8" and hit "Submit":

Enjoy!

More Java EE 6 features to be shown in subsequent blogs.

Technorati: totd javaee glassfish v3 javaserverfaces ajax jpa cdi beanvalidation

Tuesday Sep 16, 2008

TOTD #45: Ajaxifying Java Server Faces using JSF Extensions


TOTD #42 explained how to create a simple Java Server Faces application using NetBeans 6.1 and deploy on GlassFish. In the process it explained some basic JSF concepts as well. If you remember, it built an application that allows you to create a database of cities/country of your choice. In that application, any city/country combination can be entered twice and no errors are reported.

This blog entry extends TOTD #42 and show the list of cities, that have already been entered, starting with the letters entered in the text box. And instead of refreshing the entire page, it uses JSF Extensions to make an Ajax call to the endpoint and show the list of cities based upon the text entered. This behavior is similar to Autocomplete and shows the suggestions in a separate text box.

Let's get started!
  1. Download latest JSF-Extensions release.
  2. Unzip the bundle as:

    ~/tools >gunzip -c ~/Downloads/jsf-extensions-0.1.tar.gz | tar xvf -
  3. In NetBeans IDE, add the following jars to Project/Libraries

  4. Edit "welcomeJSF.jsp"
    1. Add the following to the required tag libraries

      <%@taglib prefix="jsfExt" uri="http://java.sun.com/jsf/extensions/dynafaces" %>

      The updated page looks like:

    2. Add the following tag as the first tag inside <f:view>

      <jsfExt:scripts />

      The updated page looks like:

    3. Add prependId="false" to "<h:form>" tag. The updated tag looks like:

    4. Add the following fragment as an attribute to <h:inputText> tag with "cityName" id:

      onkeyup="DynaFaces.fireAjaxTransaction(this, { execute: 'cityName', render: 'city_choices', immediate: true});"

      This is the magic fragment that issues an Ajax call to the endpoint. It ensures execute portion of the request lifecycle is executed for "cityName" and "city_choices" (defined later) is rendered.

      The updated page looks like:

    5. Add a new <h:outputText> tag after <h:commandButton> tag (to hold the suggestions output):

      <h:outputText id="city_choices" value="#{dbUtil.cityChoices}"></h:outputText>

      The updated page looks like:

  5. Add the following fragment to web.xml

           <init-param>
              <param-name>javax.faces.LIFECYCLE_ID</param-name>
              <param-value>com.sun.faces.lifecycle.PARTIAL</param-value>
            </init-param>

    The updated file looks like:

  6. Edit "server.Cities" class
    1. Add a new NamedQuery in Cities class (at the mark after yellow-highlighted parentheses):




      The query is:

      @NamedQuery(name = "Cities.findSimilarName", query = "SELECT c FROM Cities c WHERE LOWER(c.cityName) LIKE :searchString"),

      This NamedQuery queries the database and return a list of city names that matches the pattern specified in "searchString" parameter.
    2. Change the toString() method implementation to return "cityName". The updated method looks like:



      This allows the city name to be printed clearly.
  7. Add a new method in "server.DatabaseUtil" as:

        public Collection<Cities> getCityChoices() {
            Collection<Cities> allCities = new ArrayList<Cities>();

            if (cities.getCityName() != null && !cities.getCityName().equals("")) {
                List list = entityManager.createNamedQuery("Cities.findSimilarName").
                        setParameter("searchString", cities.getCityName().toLowerCase() + "%").
                        getResultList();
                for (int i = 0; i < list.size(); i++) {
                    allCities.add((Cities) list.get(i));
                }
               
            }
            return allCities;
        }

    This method uses previously defined NamedQuery and adds a parameter for pattern matching.
Now, play time!

The list of created cities is:



If "S" is entered in the text box (http://localhost:8080/Cities/), then the following output is shown:



Entering "San", shows:



Entering "Sant" shows:



Entering "De" updates the page as:



And finally entering "Ber" shows the output as:



So you built a simple Ajaxified Java Server Faces application using JSF Extensions.

Here are some more references to look at:
  1. JSF Extensions Getting Started Guide
  2. Tech Tip: Adding Ajax to Java Server Faces Technology with Dynamic Faces
  3. JSF Extensions Ajax Reference
Java Server Faces 2.0 has Ajax functionality integrated into the spec and this should be more seamless. I'll try that next!

Please leave suggestions on other TOTD (Tip Of The Day) that you'd like to see. A complete archive of all tips is available here.

Technorati: totd mysql javaserverfaces netbeans glassfish ajax

Sunday Mar 16, 2008

Travel Schedule - Next 5 weeks

Here is my travel schedule for next 5 weeks:

Mar 17-21 Ajax World, New York Web Application Development using jMaki
Mar 25-26 The Server Side Java Symposium, Las Vegas Rails powered by GlassFish & jMaki
Mar 27 Developer Update, St Louis Westport DoubleTree, FREE event Open Source Web Services stack in GlassFish
Mar 28 Developer Update, Kansas City, FREE event Rich Internet Applications and GlassFish
Apr 16-19 FISL, Brazil Web 2.0 Application Development using jMaki and
Asynchronous Ajax for Revolutionary Web Applications

Stop by and say hello if you are present at any of the events. You'll hear about different GlassFish technologies:
  • How Metro provides enterprise-grade open source Web services stack for meeting all your needs
  • How jMaki allows you to create Rich Internet Applications
  • How Rails applications can be powered by GlassFish & jMaki
  • Asynchronous Ajax that allows you to scale your applications tremendously
  • And any other topic that you are interested in :)
Drop a comment if you are interested in a run or meal together ?

Technorati: conf glassfish metro webservices netbeans jmaki ajax newyork lasvegas stlouis kansascity brazil fisl ajaxworld tssjs

Wednesday Dec 12, 2007

TOTD #20: How to create a new jMaki widget ?

This TOTD explains how to create a new jMaki widget and make it available in the NetBeans palette.

In order to create a jMaki widget, it's important to understand the jMaki Widget Model.

Basically, "component.htm", "component.js" and an optional "component.css" together make a jMaki widget.

Here are the files for a Hello World widget that takes an argument, concatenates it with the string "Hello" and displays the result on the page.

component.htm

<div id="${uuid}" class="hello"></div>

component.js

jmaki.namespace("jmaki.widgets.hello");

jmaki.widgets.hello.Widget = function(wargs) {
  var hello = document.getElementById(wargs.uuid);
  hello.innerHTML = "Hello " + wargs.args.name;
}

component.css

.hello {
  font-size: 22px;color: red;
}

The following files are required if you like to package your component as a reusable widget library in the NetBeans IDE:

hello.jsp

<a:widget name="hello" args="{name: 'Duke'}" />

Bundle.properties (top-level)

jMaki.Library.Name=jMaki Hello Widget

Bundle.properties (templates)

NAME_templates.hello=Hello
HINT_templates.hello=<html>Hello</html>

widget.json

{
  'name': 'Hello',
  'type': 'custom',
  'version': '1.0',
  'jMakiVersion': '1.0'
}

Package these files together in the following directory structure (choose any zip file name):

Bundle.properties
resources
  hello
    component.htm
    component.js
    component.css
    widget.json (optional)
templates
   hello
     hello.jsp
     Bundle.properties

And then you zip up these files together, that's it! Now this zip file can be added to the jMaki palette in the NetBeans IDE as shown here. Really simple!

After the widget is added to NetBeans palette, it looks like as shown below:

Now, just like any other jMaki widget, you can drag-and-drop "Hello" from the jMaki palette in your JSP page and the following code fragment is generated:

<a:widget name="hello" args="{name: 'Duke'}" />

After the application is deployed, the page is rendered in the browser as shown below:

Couple of points ...

  1. Templates for other languages such as Ruby or PHP can be added in the templates directory. This enables drag-and-drop of your widget in those languages as well.
  2. It's important to maintain the case sensitivity of the property names in Bundle.properties otherwise they will not be recognized.

Please leave suggestions on other TOTD that you'd like to see. A complete archive is available here.

Technorati: totd jmaki web2.0 widgets ajax netbeans

Thursday Apr 19, 2007

AJAX vs Ajax - Ajax ofcourse!

Ajax is a popular term for past few months but is still being written incorrectly as "AJAX" (all capitals) instead of "Ajax" (camel case). I started using AJAX but then corrected myself and have been using Ajax since then. So the correct term is Ajax, not AJAX.

Here is a list of several reasons (some mine and others from my colleague Rick's list):

  1. Jesse James Garrett coined the term as Ajax, not AJAX.
    1. A quote from the source "The name is shorthand for Asynchronous JavaScript + XML". It is intended to be a shorthand, not an acronym. And notice it is "+", not an "and" indicating a collection of technologies.
    2. Another quote from the source "I needed something shorter than “Asynchronous JavaScript+CSS+DOM+XMLHttpRequest” to use when discussing this approach with clients.". Ajax is not just Asynchronous JavaScript and XML, it's CSS and DOM as well. Moreover JSON is becoming a more popular format for data interchange. Should "AJAX" then instead be coined as "AJAJ" ? Or if an application happen to use Text instead, will they call it as "AJAT" ?
    3. In an interview on The story behind Ajax, Jesse said "I thought of Ajax as a convenient [term]. It was never intended as an acronym.".

I think the above three bullets should be sufficient to convince anybody to use "Ajax" instead of "AJAX". But if not, here are some more reasons to switch to the correct usage of term:

  1. Wikipedia entry clarifies that Ajax is not expected to be an acronym.
  2. A Google Fight between AJAX and Ajax shows exactly same numbers and still tries to predict a winner. Is that a bug ?
  3. Another reference to Ajax vs AJAX.
  4. Bye Bye "AJAX", The Age of "Ajax" is Nigh - If AJAX is indeed an acronym (which it's not) then a comment on the article points out some others as:
    AJACX: Asynchronous JavaScript, CSS and XMLHttpRequest
    ADJACS: Asynchronous DOM, JavaScript and CSS
    ADHJACS: Asynchronous DOM, HTML, JavaScript and CSS
    AJACHS: Asynchronous JavaScript, HTML and CSS
    AJACS: Asynchronous JavaScript, HTML and CSS
  5. Dion's (Ajaxian co-founder) first prediction for 2007 is "Ajax beats AJAX in all but bad newspapers."
  6. Here is a Google survey of some publishers of Ajax books. They all seem to be using "Ajax", not "AJAX".
  7. Some of the common vendors use Ajax
    1. IBM
    2. HP
    3. Oracle
    4. BEA
    5. Adobe

Now there should be no reason to use "AJAX". However if you still feel like using this term, please leave a comment on this blog and let's talk. There are some incorrect usages in sun.com and I'll follow up to get them fixed.

Technorati: ajax Ajax AJAX

Friday Mar 23, 2007

Day 1 @ The Server Side Java Symposium

I've been in Las Vegas for past 2 days attending The Server Side Java Symposium. Sun is the only platinum sponsor.

The conference is at The Venetian, one of the nicest hotels on the strip, but found two irritating issues for working people:

  • Using fitness center facilities require you to pay $35/day charge. That is ridiculous to me. They anyway charge fortune for the room so why this extra fee ? I used the facility yesterday without knowing the charge but found out about the charge as there were folks lined up on the "reservation desk" for the fitness center. I've never seen that for a fitness center in a hotel.
  • There are no power connections on the office table. There is a personalized fax machine but I'd rather have a power connection to make it convenient.

TheServerSide sponsored the travel and lodging and check out the pictures of the suite, it's pretty cool!

 

I missed the opening keynote by Karen Tegan Padir but heard it went well. Later that day, I attended a session by Ben Galbraith and Dion Alamer (co-founders of Ajaxian) on "State of Ajax".

The session started by asking "Does anyone here not know how to do Ajax ?". There were few hands raised and so the session started by creating a simple HTML form that takes a zip code and returns the corresponding city using XMLHttpRequest without any page refresh. Then the talk explained three main Ajaxian architectures:

  • Return data (JSON / XML) - Smart clients, parse XML and JSON and populate the front end.
  • Return HTML (responseText + innerHTML) - Slightly dumb client, just shows the results as is.
  • Return JavaScript (eval) - Really dumb client, invoke the script sent by server.

The talk identified Google Maps, Google Suggest, HousingmapsTaDaList as Ajax innovators. In my opinion, Google Suggest was really the first effort that showed Ajax-like interactions.

Ben and Dion divided JavaScript in two camps: "JavaScript is Good" and "JavaScript is Bad". jMaki was classified in the first camp, Google Web Toolkit in the second camp and Direct Web Remoting in partly both the camps. Project Phobos was also classified in "JavaScript is Good" camp as it enables server-side scripting. Ben will be uploading a new video on jMaki showing Craig's list mashup so stay tuned for that.

Prototype, Scriptaculous and Dojo were rated as the most popular toolkits in a survey conducted last year on Ajaxian. The speakers classified Dojo as "Huge Elephant of JavaScript" with support for offline storage, presentation, remoting, charts and many other features.

IntelliJ IDEA 6.0 and NetBeans 5.5 for development and FireBug for debugging were the recommended tools. Then there were few slides on offline storage, especially the upcoming capabilities in Firefox 3 (off-line cache, off-line events, persistent cache), dojo.storage package and Adobe Apollo with offline flash. There was a brief mention of Project Tamarin that will provide approx 10 times faster JavaScript runtime and this will be integrated in a later version of Firefox. And the talk concluded by giving a future slide including topics such as off-line Ajax, fast JavaScript interpreters, HTML 5 and others.

A complete Day 1 report is available here. Ed Ort also posted notes.

Technorati: theserverside Ajax venetian

About

profile image
Arun Gupta is a technology enthusiast, a passionate runner, author, and a community guy who works for Oracle Corp.


Java EE 7 Samples

Stay Connected

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today