RichFaces-Fast-JSF

From Resin 3.0

(Difference between revisions)
Jump to: navigation, search
m (Running RichFaces Calendar Sample)
m
 
(5 intermediate revisions by one user not shown)
Line 494: Line 494:
 
== Running RichFaces Calendar Sample ==
 
== Running RichFaces Calendar Sample ==
 
Below is an outline of steps needed in order to run RichFaces Calendar Sample
 
Below is an outline of steps needed in order to run RichFaces Calendar Sample
<lu>
+
<ul>
<li>Deploy the Calendar Sample application into ''$RESIN-HOME/webapps/calendar</li>
+
<li>Deploy the Calendar Sample application into ''$RESIN-HOME/webapps/calendar-sample</li>
<li>Change to the webapps/calendar/WEB-INF/lib and delete the following files: calendar-3.1*.jar, jsf-api-1.2_*.jar, jsf-impl-1.2_*.jar, jstl-1.*.jar, xercesImpl-2.4*.jar</li>
+
<li>Change to the calendar-sample's WEB-INF/lib directory and delete the following files: calendar-3.1.*.jar, jsf-api-1.2_*.jar, jsf-impl-1.2_*.jar, jstl-1.*.jar, xercesImpl-2.*.jar</li>
<li>Locate richfaces-ui-3.1.*.GA.jar and copy it into the WEB-INF/lib directory</li>
+
<li>Locate richfaces-ui-3.1.*.GA.jar in RichFaces's distribution and copy it into the WEB-INF/lib directory</li>
<li>Open ''pages/Calendar.jsp'' page of the web application and change <code><pre><%@ taglib uri="http://labs.jboss.com/jbossrichfaces/ui/calendar" prefix="calendar" %>
+
<li>Open for editing ''pages/Calendar.jsp'' page of the web application and change ''taglib uri="http://labs.jboss.com/jbossrichfaces/ui/calendar"'' to ''taglib uri="http://richfaces.org/rich"''</li>
</pre></code> to <code><pre><%@ taglib uri="http://richfaces.org/rich" prefix="calendar" %></pre></code></li>
+
<li>Create WEB-INF/resin-web.xml file with the following content
 +
<code><pre>
 +
<web-app xmlns='http://caucho.com/ns/resin'>
 +
  <jsf fast-jsf='true'/>
 +
</web-app>
 +
</pre></code>
 +
</li>
 +
<li>Create ''ajax4jsf-3.1.5.ftld'' and ''richfaces-3.1.5.ftld'' files in WEB-INF/classes/META-INF by copying content from above</li>
 +
<li>Start Resin</li>
 +
<li>Navigate to http://localhost:8080/calendar-sample/pages/Calendar.jsf</li>
 +
<li>For deeper understanding of what goes on under the hood: </li>
 +
<ul>
 +
  <li>explore ''WEB-INF/work/_jsp/pages/_Calendar__jsp.java''</li>
 +
  <li>delete the WEB-INF/work directory</li>
 +
  <li>set fast-jsf to false</li>
 +
  <li>navigate to http://localhost:8080/calendar-sample/pages/Calendar.jsf</li>
 +
  <li>explore ''WEB-INF/work/_jsp/pages/_Calendar__jsp.java'' again</li>
 +
</ul>
  
 
+
</ul>
</lu>
+

Latest revision as of 23:10, 26 June 2008

Contents

[edit] Running RichFaces and Ajax4JSF applications in fast-jsf mode

[edit] Fast JSF

Resin allows running your JSF applications in fast jsf mode. Fast JSF mode is applied to JSP code generator making it bypass JSP tags and use the component classes directly to construct component tree defined in the JSP file. To enable fast JSF mode for a particular library Resin needs to know which components the tags bind to. E.g. in a standard JSF library a h:message component would bind to javax.faces.component.html.HtmlMessage and Resin knows it from the following binding included in Resin's distribution.

<jsf-taglib xmlns="http://caucho.com/ns/resin">
  <uri>http://java.sun.com/jsf/html</uri>
   ...
  <jsf-tag>
    <name>messages</name>
    <component-class>javax.faces.component.html.HtmlMessages</component-class>
  </jsf-tag>
  ...
</jsf-tablib>

For RichFaces two bindings are needed: one for the base Ajax4JSF library and another for RichFaces UI. The bindings are loaded by web application class loader from resources that match META-INF/*.ftld naming pattern, thus they can be placed in my-app/WEB-INF/classes/META-INF or packaged into a jar and placed in my-app/WEB-INF/lib

[edit] Ajax4JSF

META-INF/ajax4jsf-3.1.5.ftld

<?xml version='1.0'?>
<jsf-taglib xmlns='http://caucho.com/ns/resin'>
	<uri>http://richfaces.org/a4j</uri>
	<jsf-tag>
		<name>actionparam</name>
		<component-class>org.ajax4jsf.component.html.HtmlActionParameter</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>commandButton</name>
		<component-class>org.ajax4jsf.component.html.HtmlAjaxCommandButton</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>commandLink</name>
		<component-class>org.ajax4jsf.component.html.HtmlAjaxCommandLink</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>form</name>
		<component-class>org.ajax4jsf.component.html.AjaxForm</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>include</name>
		<component-class>org.ajax4jsf.component.html.Include</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>jsFunction</name>
		<component-class>org.ajax4jsf.component.html.HtmlAjaxFunction</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>loadBundle</name>
		<component-class>org.ajax4jsf.component.html.AjaxLoadBundle</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>loadScript</name>
		<component-class>org.ajax4jsf.component.html.HtmlLoadScript</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>loadStyle</name>
		<component-class>org.ajax4jsf.component.html.HtmlLoadStyle</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>log</name>
		<component-class>org.ajax4jsf.component.html.AjaxLog</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>mediaOutput</name>
		<component-class>org.ajax4jsf.component.html.MediaOutput</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>outputPanel</name>
		<component-class>org.ajax4jsf.component.html.HtmlAjaxOutputPanel</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>page</name>
		<component-class>org.ajax4jsf.component.html.HtmlPage</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>poll</name>
		<component-class>org.ajax4jsf.component.html.AjaxPoll</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>portlet</name>
		<component-class>org.ajax4jsf.component.html.HtmlPortlet</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>push</name>
		<component-class>org.ajax4jsf.component.html.AjaxPush</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>region</name>
		<component-class>org.ajax4jsf.component.html.HtmlAjaxRegion</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>repeat</name>
		<component-class>org.ajax4jsf.component.html.HtmlAjaxRepeat</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>status</name>
		<component-class>org.ajax4jsf.component.html.HtmlAjaxStatus</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>support</name>
		<component-class>org.ajax4jsf.component.html.HtmlAjaxSupport</component-class>
	</jsf-tag>
</jsf-taglib>

[edit] RichFaces

META-INF/richfaces-3.1.5.ftld

<?xml version='1.0'?>
<jsf-taglib xmlns='http://caucho.com/ns/resin'>
	<uri>http://richfaces.org/rich</uri>
	<jsf-tag>
		<name>calendar</name>
		<component-class>org.richfaces.component.html.HtmlCalendar</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>column</name>
		<component-class>org.richfaces.component.html.HtmlColumn</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>columnGroup</name>
		<component-class>org.richfaces.component.html.HtmlColumnGroup</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>componentControl</name>
		<component-class>org.richfaces.component.html.HtmlComponentControl</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>contextMenu</name>
		<component-class>org.richfaces.component.html.HtmlContextMenu</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>dataDefinitionList</name>
		<component-class>org.richfaces.component.html.HtmlDataDefinitionList</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>dataFilterSlider</name>
		<component-class>org.richfaces.component.html.HtmlDataFilterSlider</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>dataGrid</name>
		<component-class>org.richfaces.component.html.HtmlDataGrid</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>dataList</name>
		<component-class>org.richfaces.component.html.HtmlDataList</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>dataOrderedList</name>
		<component-class>org.richfaces.component.html.HtmlDataOrderedList</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>dataTable</name>
		<component-class>org.richfaces.component.html.HtmlDataTable</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>datascroller</name>
		<component-class>org.richfaces.component.html.HtmlDatascroller</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>dndParam</name>
		<component-class>org.richfaces.component.html.HtmlDndParam</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>dragIndicator</name>
		<component-class>org.richfaces.component.html.HtmlDragIndicator</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>dragSupport</name>
		<component-class>org.richfaces.component.html.HtmlDragSupport</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>dropDownMenu</name>
		<component-class>org.richfaces.component.html.HtmlDropDownMenu</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>dropSupport</name>
		<component-class>org.richfaces.component.html.HtmlDropSupport</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>effect</name>
		<component-class>org.richfaces.component.html.HtmlEffect</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>gmap</name>
		<component-class>org.richfaces.component.html.HtmlGmap</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>inputNumberSlider</name>
		<component-class>org.richfaces.component.html.HtmlInputNumberSlider</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>inputNumberSpinner</name>
		<component-class>org.richfaces.component.html.HtmlInputNumberSpinner</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>insert</name>
		<component-class>org.richfaces.ui.component.html.HtmlInsert</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>jQuery</name>
		<component-class>org.richfaces.component.html.HtmlJQuery</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>listShuttle</name>
		<component-class>org.richfaces.component.html.HtmlListShuttle</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>menuGroup</name>
		<component-class>org.richfaces.component.html.HtmlMenuGroup</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>menuItem</name>
		<component-class>org.richfaces.component.html.HtmlMenuItem</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>menuSeparator</name>
		<component-class>org.richfaces.component.html.HtmlMenuSeparator</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>message</name>
		<component-class>org.richfaces.component.html.HtmlRichMessage</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>messages</name>
		<component-class>org.richfaces.component.html.HtmlRichMessages</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>modalPanel</name>
		<component-class>org.richfaces.component.html.HtmlModalPanel</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>orderingList</name>
		<component-class>org.richfaces.component.html.HtmlOrderingList</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>paint2D</name>
		<component-class>org.richfaces.component.html.HtmlPaint2D</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>panel</name>
		<component-class>org.richfaces.component.html.HtmlPanel</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>panelBar</name>
		<component-class>org.richfaces.component.html.HtmlPanelBar</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>panelBarItem</name>
		<component-class>org.richfaces.component.html.HtmlPanelBarItem</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>panelMenu</name>
		<component-class>org.richfaces.component.html.HtmlPanelMenu</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>panelMenuGroup</name>
		<component-class>org.richfaces.component.html.HtmlPanelMenuGroup</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>panelMenuItem</name>
		<component-class>org.richfaces.component.html.HtmlPanelMenuItem</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>recursiveTreeNodesAdaptor</name>
		<component-class>org.richfaces.component.html.HtmlRecursiveTreeNodesAdaptor</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>scrollableDataTable</name>
		<component-class>org.richfaces.component.html.HtmlScrollableDataTable</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>separator</name>
		<component-class>org.richfaces.component.html.HtmlSeparator</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>simpleTogglePanel</name>
		<component-class>org.richfaces.component.html.HtmlSimpleTogglePanel</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>spacer</name>
		<component-class>org.richfaces.component.html.HtmlSpacer</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>subTable</name>
		<component-class>org.richfaces.component.html.HtmlSubTable</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>suggestionbox</name>
		<component-class>org.richfaces.component.html.HtmlSuggestionBox</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>tab</name>
		<component-class>org.richfaces.component.html.HtmlTab</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>tabPanel</name>
		<component-class>org.richfaces.component.html.HtmlTabPanel</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>toggleControl</name>
		<component-class>org.richfaces.component.html.HtmlToggleControl</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>togglePanel</name>
		<component-class>org.richfaces.component.html.HtmlTogglePanel</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>toolBar</name>
		<component-class>org.richfaces.component.html.HtmlToolBar</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>toolBarGroup</name>
		<component-class>org.richfaces.component.html.HtmlToolBarGroup</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>toolTip</name>
		<component-class>org.richfaces.component.html.HtmlToolTip</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>tree</name>
		<component-class>org.richfaces.component.html.HtmlTree</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>treeNode</name>
		<component-class>org.richfaces.component.html.HtmlTreeNode</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>treeNodesAdaptor</name>
		<component-class>org.richfaces.component.html.HtmlTreeNodesAdaptor</component-class>
	</jsf-tag>
	<jsf-tag>
		<name>virtualEarth</name>
		<component-class>org.richfaces.component.html.HtmlVirtualEarth</component-class>
	</jsf-tag>
</jsf-taglib>

[edit] Switching the Fast JSF mode on and off

Fast JSF mode can be turned on globally or for particular context by setting fast-jsf flag to true in $RESIN-HOME/conf/resin.xml or my-app/WEB-INF/resin-web.xml. In Resin 3.2 fast-jsf mode is turned on by default.

Example of $my-app/WEB-INF/resin-web.xml that turns fast JSF mode on

<web-app xmlns='http://caucho.com/ns/resin'>
  <jsf fast-jsf='true'/>
</web-app>

[edit] Sample code for generating .ftld files

The code below was used to generate the .ftld files for RichFaces and given for reference. It will use faces-config.xml and ajax4jsf.taglib.xml with rich.taglib.xml to generate both files.

import com.caucho.vfs.Path;
import com.caucho.vfs.Vfs;
import com.caucho.xml.DOMBuilder;
import com.caucho.xml.QDocument;
import com.caucho.xml.Xml;
import com.caucho.xpath.XPath;
import com.caucho.xpath.XPathException;

import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class RichFacesFastJsfGen {


  public static void main(String[] args)
    throws IOException, XPathException, SAXException
  {
    Path path = Vfs.lookup(
      "/Users/alex/Documents/jars/richfaces-ui-3.1.5.GA/ui/assembly/target/classes/META-INF/faces-config.xml");

    QDocument facesConfig = parse(path);

    Iterator it = XPath.select("/faces-config/component", facesConfig);

    Map<String, String> typeToClass = new HashMap<String, String>();


    while (it.hasNext()) {
      Element e = (Element) it.next();
      String componentType = XPath.evalString("component-type/text()", e)
        .trim();
      String componentClass = XPath.evalString("component-class/text()", e)
        .trim();
      typeToClass.put(componentType, componentClass);
    }

    path = Vfs.lookup(
      "/Users/alex/Documents/jars/richfaces-ui-3.1.5.GA/ui/assembly/target/classes/META-INF/ajax4jsf.taglib.xml");

    QDocument taglib = parse(path);

    it = XPath.select("/facelet-taglib/tag", taglib);

    StringBuilder builder = new StringBuilder("<?xml version='1.0'?>\n");
    builder.append("<jsf-taglib xmlns='http://caucho.com/ns/resin'>\n");
    builder.append("\t<uri>http://richfaces.org/a4j</uri>\n");

    while (it.hasNext()) {
      Element e = (Element) it.next();

      String tagName = XPath.evalString("tag-name", e).trim();

      String componentType = XPath.evalString("component/component-type/text()",
                                              e).trim();

      String componentClass = typeToClass.get(componentType);

      if (componentClass != null && !"".equals(componentClass)) {
        builder.append("\t<jsf-tag>\n");
        builder.append("\t\t<name>");
        builder.append(tagName);
        builder.append("</name>\n");
        builder.append("\t\t<component-class>");
        builder.append(componentClass);
        builder.append("</component-class>\n");
        builder.append("\t</jsf-tag>\n");
      }

    }

    builder.append("</jsf-taglib>");

    System.out.println(builder);

    path = Vfs.lookup(
      "/Users/alex/Documents/jars/richfaces-ui-3.1.5.GA/ui/assembly/target/classes/META-INF/rich.taglib.xml");

    taglib = parse(path);

    it = XPath.select("/facelet-taglib/tag", taglib);

    builder = new StringBuilder("<?xml version='1.0'?>\n");
    builder.append("<jsf-taglib xmlns='http://caucho.com/ns/resin'>\n");
    builder.append("\t<uri>http://richfaces.org/rich</uri>\n");

    while (it.hasNext()) {
      Element e = (Element) it.next();

      String tagName = XPath.evalString("tag-name", e).trim();

      String componentType = XPath.evalString("component/component-type/text()",
                                              e).trim();

      String componentClass = typeToClass.get(componentType);

      if (componentClass != null && !"".equals(componentClass)) {
        builder.append("\t<jsf-tag>\n");
        builder.append("\t\t<name>");
        builder.append(tagName);
        builder.append("</name>\n");
        builder.append("\t\t<component-class>");
        builder.append(componentClass);
        builder.append("</component-class>\n");
        builder.append("\t</jsf-tag>\n");
      }

    }

    builder.append("</jsf-taglib>");

    System.out.println(builder);

  }

  public static QDocument parse(Path file)
    throws IOException, SAXException, XPathException
  {

    QDocument doc = new QDocument();

    DOMBuilder builder = new DOMBuilder();

    builder.init(doc);

    Xml xml = new Xml();
    xml.setOwner(doc);
    xml.setNamespaceAware(false);
    xml.setContentHandler(builder);

    xml.parse(file);

    return doc;
  }
}

[edit] Running RichFaces Calendar Sample

Below is an outline of steps needed in order to run RichFaces Calendar Sample

  • Deploy the Calendar Sample application into $RESIN-HOME/webapps/calendar-sample
  • Change to the calendar-sample's WEB-INF/lib directory and delete the following files: calendar-3.1.*.jar, jsf-api-1.2_*.jar, jsf-impl-1.2_*.jar, jstl-1.*.jar, xercesImpl-2.*.jar
  • Locate richfaces-ui-3.1.*.GA.jar in RichFaces's distribution and copy it into the WEB-INF/lib directory
  • Open for editing pages/Calendar.jsp page of the web application and change taglib uri="http://labs.jboss.com/jbossrichfaces/ui/calendar" to taglib uri="http://richfaces.org/rich"
  • Create WEB-INF/resin-web.xml file with the following content
    <web-app xmlns='http://caucho.com/ns/resin'>
      <jsf fast-jsf='true'/>
    </web-app>
    
  • Create ajax4jsf-3.1.5.ftld and richfaces-3.1.5.ftld files in WEB-INF/classes/META-INF by copying content from above
  • Start Resin
  • Navigate to http://localhost:8080/calendar-sample/pages/Calendar.jsf
  • For deeper understanding of what goes on under the hood:
Personal tools