Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: removed of biz-gwt because it is not accessible anymore
Note
titleOther WIPs

There are also 2 related Google code projects

ofbiz-gwt

Overview

Why GWT?  I am currently working on a client project that required a rich user interface experience.  Developing the interactivity with manual javascript (prototype) coding was painfully slow and difficult to get working consistently across multiple browser versions.

...

Download GWT SDK (I used GWT 2.0.3).Unzip GWT into OFBIZ_HOME. My OFBIZ directory looks like this:

Code Block

ofbiz
  +- applications
  +- bin
  +- debian
  +- framework
  +- gwt-2.0.3
       +- doc
       +- samples
  +- hot-deploy
  +- runtime
  +- specialpurpose
  +- themes
  +- tools

Step 2 - create an ofbiz component

Code Block

snowch@dl:~/workspace/ofbiz$ ./ant create-component
Buildfile: build.xml
Trying to override old definition of datatype javacc
Trying to override old definition of datatype jjtree

create-component:
    [input] Component name: (e.g. mycomponent) [Mandatory]
gwtdemo
    [input] Component resource name: (e.g. MyComponent) [Mandatory]
GwtDemo
    [input] Webapp name: (e.g. mycomponent) [Mandatory]
gwtdemo
    [input] Base permission: (e.g. MYCOMPONENT) [Mandatory]
GWTDEMO
     [echo] The following hot-deploy component will be created:
     [echo]               Name: gwtdemo
     [echo]               Resource Name: GwtDemo
     [echo]               Webapp Name: gwtdemo
     [echo]               Base permission: GWTDEMO
     [echo]               Folder: /home/snowch/workspace/ofbiz/hot-deploy/gwtdemo
     [echo]
    [input] Confirm:  (Y, [N], y, n)
y

...

Create the gwt module descriptor xml file: src/org/example/gwtdemo.gwt.xml

Code Block

<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='gwtdemo'>
  
  <inherits name='com.google.gwt.user.User'/>

  <inherits name='com.google.gwt.user.theme.standard.Standard'/>
  <!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
  <!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/>     -->

  <entry-point class='org.example.client.gwtdemo'/>

  <source path='client'/>
  <source path='shared'/>

</module>

...

Add the following properties to your build.xml file below the <import file="../../common.xml"/> tag

Code Block

	<property name="gwt.args" value="-war webapp/gwtdemo/gwtpages" />
	<property name="gwt.sdk" location="../../gwt-2.0.3" />
	<property name="gwt.webapp.name" value="org.example.gwtdemo" />

...

And the following just before the </project> tag:

Code Block


    <!-- ================================================================= -->
    <!--                                                  GWT Targets                                     -->
    <!-- ================================================================= -->
	
	<target name="libs" description="Copy libs to ${build}/lib">
		<mkdir dir="${build.dir}/lib" />
		<copy todir="${build.dir}/lib" file="${gwt.sdk}/gwt-servlet.jar" />
		<!-- Add any additional server libs that need to be copied -->
	</target>
	
	<target name="javac" depends="libs" description="Compile java source">
		<mkdir dir="${build.dir}/classes"/>
		<javac srcdir="src" includes="**" encoding="utf-8"
        destdir="${build.dir}/classes"
        source="1.5" target="1.5" nowarn="true"
        debug="true" debuglevel="lines,vars,source">
			<classpath refid="local.class.path"/>
		</javac>
		<copy todir="${build.dir}/classes">
			<fileset dir="src" excludes="**/*.java"/>
		</copy>
	</target>

	<target name="gwtc" depends="javac" description="GWT compile to JavaScript">
		<java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
			<classpath>
				<pathelement location="src"/>
				<path refid="local.class.path"/>
			</classpath>
			<!-- add jvmarg -Xss16M or similar if you see a StackOverflowError -->
			<jvmarg value="-Xmx256M"/>
			<!-- Additional arguments like -style PRETTY or -logLevel DEBUG -->
			<arg line="${gwt.args}"/>
			<arg value="${gwt.webapp.name}"/>
		</java>
	</target>

	<target name="jar" depends="javac, gwtc">
		<jar jarfile="${build.dir}/lib/${name}.jar">
			<fileset dir="${build.dir}/classes"/>
		</jar>
	</target>

	<target name="build" depends="gwtc, jar" description="Build this project" />

...

Create the following file: src/org/example/client/gwtdemo.java

Code Block

package org.example.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.RootPanel;

public class gwtdemo implements EntryPoint {

    public void onModuleLoad() {
	  
    final Button helloButton = new Button("Say Hello");
  
    helloButton.addClickHandler(new ClickHandler() {
		@Override
		public void onClick(ClickEvent arg0) {
			DialogBox dialog = new DialogBox();
			dialog.setAutoHideEnabled(true);
			dialog.setText("Hello World");
			dialog.center();
			dialog.show();
		}
    });
    
    RootPanel.get("helloButtonContainer").add(helloButton);
  }
}

...

change to your component's top level folder and run ant

Code Block

snowch@dl:~/workspace/ofbiz$ cd hot-deploy/gwtdemo/
snowch@dl:~/workspace/ofbiz/hot-deploy/gwtdemo$ ../../ant
Buildfile: build.xml
Trying to override old definition of datatype javacc
Trying to override old definition of datatype jjtree

libs:
    [mkdir] Created dir: /home/snowch/workspace/ofbiz/hot-deploy/gwtdemo/build/lib
     [copy] Copying 1 file to /home/snowch/workspace/ofbiz/hot-deploy/gwtdemo/build/lib

javac:
    [mkdir] Created dir: /home/snowch/workspace/ofbiz/hot-deploy/gwtdemo/build/classes
    [javac] Compiling 1 source file to /home/snowch/workspace/ofbiz/hot-deploy/gwtdemo/build/classes
     [copy] Copying 1 file to /home/snowch/workspace/ofbiz/hot-deploy/gwtdemo/build/classes

gwtc:
     [java] Compiling module org.example.gwtdemo
     [java]    Compiling 6 permutations
     [java]       Compiling permutation 0...
     [java]       Compiling permutation 1...
     [java]       Compiling permutation 2...
     [java]       Compiling permutation 3...
     [java]       Compiling permutation 4...
     [java]       Compiling permutation 5...
     [java]    Compile of permutations succeeded
     [java] Linking into /home/snowch/workspace/ofbiz/hot-deploy/gwtdemo/webapp/gwtdemo/gwtpages/gwtdemo.
     [java]    Link succeeded
     [java]    Compilation succeeded -- 33.599s

jar:
      [jar] Building jar: /home/snowch/workspace/ofbiz/hot-deploy/gwtdemo/build/lib/ofbiz-gwtdemo.jar

BUILD SUCCESSFUL

...

Add the ":/gwtdemo.css:/gwtpages" to allowedPaths in web.xml:

Code Block

        <init-param>
            <param-name>allowedPaths</param-name>
            <param-value>/control:/select:/index.html:/index.jsp:/default.html:/default.jsp:/images:/includes/maincss.css:/gwtdemo.css:/gwtpages</param-value>
        </init-param>

Step x - add a page to the main screen

Code Block

<?xml version="1.0" encoding="UTF-8"?>
<screens xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/widget-screen.xsd">

    <screen name="main">
        <section>
            <actions>
            	<set field="headerItem" value="main"/><!-- this highlights the selected menu-item with name = "main" -->
            	<!-- ========================================================= -->
            	<!-- load the gwt generated javascript and a custom stylesheet -->
            	<!-- ========================================================= -->
            	<set field="layoutSettings.javaScripts[+0]" value="/gwtdemo/gwtpages/gwtdemo/gwtdemo.nocache.js" global="true"/>
            	<set field="layoutSettings.styleSheets[+0]" value="/gwtdemo/gwtdemo.css" global="true"/> 				            	
            </actions>
            <widgets>
                <decorator-screen name="GwtDemoCommonDecorator" location="${parameters.mainDecoratorLocation}">
                    <decorator-section name="body">
                    	<!-- ===================================== -->
                    	<!-- Add a page to load the gwt javascript -->
                    	<!-- ===================================== -->
                    	<platform-specific>
                    		<html><html-template location="component://gwtdemo/webapp/gwtdemo/gwtdemo.ftl"/></html>
                    	</platform-specific>                    
                    </decorator-section>
                </decorator-screen>
            </widgets>
        </section>
    </screen>
</screens>

...

Create the gwtdemo.ftl page that is used to load the gwt pages.

Code Block

<!doctype html>

    <!-- OPTIONAL: include this if you want history support -->
    <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
    
    <!-- RECOMMENDED if your web app will not function without JavaScript enabled -->
    <noscript>
      <div style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif">
        Your web browser must have JavaScript enabled
        in order for this application to display correctly.
      </div>
    </noscript>

    <h1>Web Application Starter Project</h1>

    <table align="center">
      <tr>
        <td id="helloButtonContainer"></td>
      </tr>
    </table>

Step x - create the webapp/gwtdemo/gwtdemo.css page

Code Block

/** Most GWT widgets already have a style name defined */
.gwt-DialogBox {
  width: 400px;
}

.dialogVPanel {
  margin: 5px;
}

.serverResponseLabelError {
  color: red;
}

/** Set ids using widget.getElement().setId("idOfElement") */
#closeButton {
  margin: 15px 6px 6px;
}

...

Either grant admin user GWTDEMO_VIEW permission, or comment out widget/CommonScreens.xml permission condition:

Code Block

    <screen name="GwtDemoCommonDecorator">
        <section>
            <actions>
            </actions>
            <widgets>
                <decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}">
                    <decorator-section name="body">
                        <section>
<!--
                            <condition>
                                <if-has-permission permission="GWTDEMO" action="_VIEW"/>
                            </condition>
-->
                            <widgets>
                                <decorator-section-include name="body"/>
                            </widgets>
                            <fail-widgets>
                                <label style="h3">${uiLabelMap.GwtDemoViewPermissionError}</label>
                            </fail-widgets>
                        </section>
                    </decorator-section>
                </decorator-screen>
            </widgets>
        </section>
    </screen>

...

GWT RPC with ofbiz with Authentication:

Code Block

package cs.server;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import javolution.util.FastMap;

import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.entity.DelegatorFactory;
import org.ofbiz.entity.GenericDelegator;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.service.GenericDispatcher;
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ServiceUtil;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import cs.client.GreetingService;
import cs.shared.AuthenticatorException;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements
    GreetingService {

  public String greetServer(String input) throws AuthenticatorException {
    
	GenericDelegator delegator = (GenericDelegator) DelegatorFactory.getDelegator("default");
	LocalDispatcher dispatcher = GenericDispatcher.getLocalDispatcher("default",delegator); 

	HttpServletRequest request = this.getThreadLocalRequest();
	HttpSession session = request.getSession();
	
	if (session == null) {
		throw new AuthenticatorException("Session not found");
	}
	
	GenericValue userLogin = (GenericValue) session.getAttribute("userLogin");
	if (userLogin == null) {
		throw new AuthenticatorException("User login not found");
	}
	
	Map<String, String> paramMap = UtilMisc.toMap( 
			"userLogin", userLogin,
			"message", input
		);
	
	Map<String, Object> result = FastMap.newInstance();
	try {
		result = dispatcher.runSync("ping", paramMap);
	} catch (GenericServiceException e1) {
		Debug.logError(e1, GreetingServiceImpl.class.getName());
		return e1.toString();
	}
	
	if (ServiceUtil.isSuccess(result)) {    	
		return "RESPONSE: *** " + result.get("message") + " ***";
	}
	
	if (ServiceUtil.isError(result) || ServiceUtil.isFailure(result)) {
		return ServiceUtil.getErrorMessage(result);
	}
	
	// shouldn't ever get here ... should we?
	throw new RuntimeException("Invalid ");
  }
}