Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Tapestry Wiki" for 
change notification.

The following page has been changed by DanielJue:
http://wiki.apache.org/tapestry/Tapestry5GWTIntegration

------------------------------------------------------------------------------
  = Tapestry 5 GWT Integration =
- 
+ [http://www.phy6.net/downloads/T5GWT/myapp.zip Download the Source code and 
Project]
  This article is on making use of both of these technologies.
- 
+ [http://www.phy6.net/downloads/T5GWT/myapp.png]
  ==== Reader Requirements ====
  
   *Basic knowledge of T5 features
   *Know how to create the hello world archetype of both T5 and GWT.
   *very basic Maven knowledge
+  *Suggest you read through the first GWT tutorial, linked from the wiki page.
  
  ==== Technologies Used ====
  
@@ -32, +33 @@

  
  
  
- === More in a bit ===
+ === Lets get you set up ===
+ You can download the whole project using the link above.  Here's the POM for 
you to look at:
  
- What I will show here:
+ '''full pom.xml'''
  
- A single project using WTP, includes Tapestry 5 and GWT in one project.
- Modifying the POM and Web XML for new entrypoints.
- Maven and or CMD file to execute gwt builds
- Multiple simple components on one page
- Multiple instances of the same RPC component on one page!
+ {{{
+ <project
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns="http://maven.apache.org/POM/4.0.0";>
+       <modelVersion>4.0.0</modelVersion>
+       <groupId>org.example</groupId>
+       <artifactId>myapp</artifactId>
+       <version>1.0.0-SNAPSHOT</version>
+       <packaging>war</packaging><!--
+       First use clean compile gwt:compile, and afterwards you can just run 
the compile.cmd that gets generated.
+       Remember to refresh your source directory before serving this, since 
the GWT compilation outputs into a source dir!
+       --><name>myapp Tapestry 5 Application</name>
+       <dependencies>
+       <!--  GWT deps (from central repo) -->
+               <dependency>
+                       <groupId>com.google.gwt</groupId>
+                       <artifactId>gwt-servlet</artifactId>
+                       <version>${gwtVersion}</version>
+                       <scope>runtime</scope>
+               </dependency>
+               <dependency>
+                       <groupId>com.google.gwt</groupId>
+                       <artifactId>gwt-user</artifactId>
+                       <version>${gwtVersion}</version>
+                       <scope>provided</scope>
+               </dependency>
+               <dependency>
+                       <groupId>com.google.gwt</groupId>
+                       <artifactId>gwt-dev</artifactId>
+                       <version>${gwtVersion}</version>
+                       <classifier>${platform}-libs</classifier>
+                       <type>zip</type>
+                       <scope>provided</scope>
+               </dependency>
+               <dependency>
+                       <groupId>com.google.gwt</groupId>
+                       <artifactId>gwt-dev</artifactId>
+                       <version>${gwtVersion}</version>
+                       <classifier>${platform}</classifier>
+                       <scope>provided</scope>
+               </dependency>
+               <dependency>
+                       <groupId>log4j</groupId>
+                       <artifactId>log4j</artifactId>
+                       <version>1.2.14</version>
+               </dependency>
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <version>4.1</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.tapestry</groupId>
+                       <artifactId>tapestry-core</artifactId>
+                       <version>${tapestry-release-version}</version>
+               </dependency>
+               <!--
+                       A dependency on either JUnit or TestNG is required, or 
the surefire
+                       plugin (which runs the tests) will fail, preventing 
Maven from
+                       packaging the WAR. Tapestry includes a large number of 
testing
+                       facilities designed for use with TestNG 
(http://testng.org/), so it's
+                       recommended.
+               -->
+               <dependency>
+                       <groupId>org.testng</groupId>
+                       <artifactId>testng</artifactId>
+                       <version>5.1</version>
+                       <classifier>jdk15</classifier>
+                       <scope>test</scope>
+               </dependency>
+       </dependencies>
+       <build>
+               <finalName>myapp</finalName>
+               <resources>
+                       <resource>
+                               <directory>src/main/resources</directory>
+                               <includes>
+                                       <include>**</include>
+                               </includes>
+                               <excludes>
+                                       <exclude>hibernatecfg/*</exclude>
+                                       <exclude>hibernate.cfg.xml</exclude>
+                                       <exclude>log4j.properties</exclude>
+                                       <exclude>spy.properties</exclude>
+                                       <exclude>version.properties</exclude>
+                                       <exclude>**/.svn/**</exclude>
+                               </excludes>
+                       </resource>
+                       <resource>
+                               <directory>src/main/java</directory>
+                               <includes>
+                                       <include>**/*</include>
+                               </includes>
+                               <excludes>
+                                       <exclude>**/*.java</exclude>
+                                       <exclude>**/.svn/**</exclude>
+                               </excludes>
+                       </resource>
+               </resources>
+               <plugins>
+ <!--  configure the GWT-Maven plugin -->
+                       <plugin>
+                               <groupId>com.totsp.gwt</groupId>
+                               
<artifactId>maven-googlewebtoolkit2-plugin</artifactId>
+                               <version>2.0-beta26</version>
+                               <configuration>
+                                       <logLevel>INFO</logLevel>
+                                       <compileTargets>
+                                               
<value>se.pmdit.tutorial.t5gwt.gwt.Sample</value>
+                                               
<value>se.pmdit.tutorial.t5gwt.gwt.ComplexSample</value>
+                                               
<value>se.pmdit.tutorial.t5gwt.gwt.StockWatcher</value>
+                                       </compileTargets>
+                                       <runTarget>/myapp/Start</runTarget>
+                                       <style>DETAILED</style>
+                                       <noServer>false</noServer>
+                                       <extraJvmArgs>-Xmx512m</extraJvmArgs>
+                                       <!--
+                                               this parameter is VERY 
important with automatic mode - has to
+                                               match the version in your 
declared deps
+                                       -->
+                                       <!--
+                                               if this is set incorrect, or 
left out and default does not match
+                                               (default is 1.5.3) you will 
have mysterious errors
+                                       -->
+                                       <gwtVersion>${gwtVersion}</gwtVersion>
+                                       <!-- This puts the GWT output 
(javascripts) into the source tree -->
+                                       <output>src/main/webapp</output >
+                               </configuration>
+                               <executions>
+                                       <execution>
+                                               <goals>
+                                                       
<!--<goal>mergewebxml</goal>
+                                                       --><!--<goal>i18n</goal>
+                                                       -->
+                                                       <goal>compile</goal>
+                                                       <!--<goal>test</goal>
+                                               -->
+                                               </goals>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <!--  Use the dependency plugin to unpack 
gwt-dev-PLATFORM-libs.zip -->
+                       <!--
+                               (this is a replacement for the old "automatic" 
mode - useful if you
+                               don't have GWT installed already, or you just 
want a maven way to
+                               handle gwt deps)
+                       -->
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-dependency-plugin</artifactId>
+                               <executions>
+                                       <execution>
+                                               <id>unpack</id>
+                                               <phase>compile</phase>
+                                               <goals>
+                                                       <goal>unpack</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <artifactItems>
+                                                               <artifactItem>
+                                                                       
<groupId>com.google.gwt</groupId>
+                                                                       
<artifactId>gwt-dev</artifactId>
+                                                                       
<version>${gwtVersion}</version>
+                                                                       
<classifier>${platform}-libs</classifier>
+                                                                       
<type>zip</type>
+                                                                       
<overWrite>false</overWrite>
+                                                                       
<outputDirectory>${settings.localRepository}/com/google/gwt/gwt-dev/${gwtVersion}</outputDirectory>
+                                                               </artifactItem>
+                                                       </artifactItems>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <!--
+                               If you want to use the target/web.xml file 
mergewebxml produces,
+                               tell the war plugin to use it. Also, exclude 
what you want from the
+                               final artifact here.
+                       -->
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-war-plugin</artifactId>
+                               <configuration><!--
+                                       
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
+                                       
--><warSourceExcludes>.gwt-tmp/**</warSourceExcludes>
+                               </configuration>
+                       </plugin>
+                       <!--  tell the compiler we can use 1.5 -->
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                               <configuration>
+                                       <source>1.5</source>
+                                       <target>1.5</target>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+ <!--  profiles (with activation per platform) -->
+       <profiles>
+               <profile>
+                       <id>gwt-dev-windows</id>
+                       <properties>
+                               <platform>windows</platform>
+                       </properties>
+                       <activation>
+                               <activeByDefault>true</activeByDefault>
+                               <os>
+                                       <family>windows</family>
+                               </os>
+                       </activation>
+               </profile>
+               <profile>
+                       <id>gwt-dev-mac</id>
+                       <properties>
+                               <platform>mac</platform>
+                       </properties>
+                       <activation>
+                               <activeByDefault>false</activeByDefault>
+                               <os>
+                                       <family>mac</family>
+                               </os>
+                       </activation>
+               </profile>
+               <profile>
+                       <id>gwt-dev-linux</id>
+                       <properties>
+                               <platform>linux</platform>
+                       </properties>
+                       <activation>
+                               <activeByDefault>false</activeByDefault>
+                               <os>
+                                       <name>linux</name>
+                               </os>
+                       </activation>
+               </profile>
+       </profiles>
+       <reporting>
+               <!--
+                       Adds a report detailing the components, mixins and base 
classes
+                       defined by this module.
+               -->
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.tapestry</groupId>
+                               
<artifactId>tapestry-component-report</artifactId>
+                               <version>${tapestry-release-version}</version>
+                               <configuration>
+                                       
<rootPackage>org.example.myapp</rootPackage>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </reporting>
+       <repositories>
+               <!--
+                       This can be commented out when the 
tapestry-release-version is a not
+                       a snapshot. The non-snapshot Tapestry artifacts are 
distributed
+                       through the central repository at ibiblio.
+               -->
+               <repository>
+                       <id>tapestry-snapshots</id>
+                       
<url>http://tapestry.formos.com/maven-snapshot-repository/
+                       </url>
+               </repository>
+               <repository>
+                       <id>codehaus.snapshots</id>
+                       <url>http://snapshots.repository.codehaus.org
+                       </url>
+               </repository>
+               <repository>
+                       <id>OpenQA_Release</id>
+                       <name>OpenQA Release Repository</name>
+                       <url>http://archiva.openqa.org/repository/releases/
+                       </url>
+               </repository>
+               <repository>
+                       <id>gwt-maven</id>
+                       <url> 
http://gwt-maven.googlecode.com/svn/trunk/mavenrepo/</url>
+               </repository>
+       </repositories>
+       <pluginRepositories>
+               <!--
+                       As above, this can be commented out when access to the 
snapshot
+                       version of a Tapestry Maven plugin is not required.
+               -->
+               <pluginRepository>
+                       <id>tapestry-snapshots</id>
+                       
<url>http://tapestry.formos.com/maven-snapshot-repository/
+                       </url>
+               </pluginRepository>
+               <pluginRepository>
+                       <id>gwt-maven-plugins</id>
+                       <url> 
http://gwt-maven.googlecode.com/svn/trunk/mavenrepo/</url>
+               </pluginRepository>
+       </pluginRepositories>
+       <properties>
+               <gwtVersion>1.5.3</gwtVersion>
+               <tapestry-release-version>5.0.18</tapestry-release-version>
+       </properties>
+ </project>
+ }}}
  
- Source code link!  The project exists already!
  
+ For now, I manually make additions to the web.xml if a servlet mapping is 
needed.  So far this example only uses one, for the Stock Prices.
+ 
+ '''web.xml'''
+ {{{ 
+ <?xml version="1.0" encoding="UTF-8"?>
+ <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee";
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd";>
+       <session-config>
+               <session-timeout> 30 </session-timeout>
+       </session-config>
+       <welcome-file-list>
+               <welcome-file>Start</welcome-file>
+       </welcome-file-list>
+       <display-name>Tapestry 5 With GWT</display-name>
+       <context-param>
+               <param-name>tapestry.app-package</param-name>
+               <param-value>se.pmdit.tutorial.t5gwt.tapestry</param-value>
+       </context-param>
+       <filter>
+               <filter-name>app</filter-name>
+               <filter-class>org.apache.tapestry5.TapestryFilter</filter-class>
+       </filter>
+       <filter-mapping>
+               <filter-name>app</filter-name>
+               <url-pattern>/*</url-pattern>
+       </filter-mapping>
+       <servlet>
+               <servlet-name>stock</servlet-name>
+               
<servlet-class>se.pmdit.tutorial.t5gwt.gwt.server.StockPriceServiceImpl</servlet-class>
+       </servlet>
+       <servlet-mapping>
+               <servlet-name>stock</servlet-name>
+               
<url-pattern>/se.pmdit.tutorial.t5gwt.gwt.StockWatcher/stockPrices</url-pattern>
+       </servlet-mapping>
+ </web-app>
+ }}}
+ 
+ 
+ 
+ === Adding GWT Targets in the POM ===
+ Notice that for each entrypoint you want to have compiled, you add it here.
+ {{{
+ ...
+                                       <compileTargets>
+                                               
<value>se.pmdit.tutorial.t5gwt.gwt.Sample</value>
+                                               
<value>se.pmdit.tutorial.t5gwt.gwt.ComplexSample</value>
+                                               
<value>se.pmdit.tutorial.t5gwt.gwt.StockWatcher</value>
+                                       </compileTargets>
+ ...
+ }}}
+ 
+ 
+ === The StockWatcher Entrypoint ===
+ {{{
+ package se.pmdit.tutorial.t5gwt.gwt.client;
+ 
+ import com.google.gwt.core.client.EntryPoint;
+ import com.google.gwt.i18n.client.Dictionary;
+ import com.google.gwt.user.client.Timer;
+ import com.google.gwt.user.client.ui.RootPanel;
+ /**
+  * 
+  * @author djue
+  *
+  */
+ public class StockWatcher implements EntryPoint {
+ 
+       private static final int REFRESH_INTERVAL = 5000; // ms
+ 
+       public void onModuleLoad() {
+ 
+               // Find all the instances in this DOM where this entry point 
should be
+               // created.
+               // The dictionary is created by
+               Dictionary gwtComponents = 
Dictionary.getDictionary("gwtComponents");
+               if (gwtComponents != null) {
+                       String str[] = 
gwtComponents.get("stockwatcher").split(",");
+                       for (int i = 0; i < str.length; i++) {
+                               createUniqueModule(str[i]);
+                       }
+               }
+ 
+       }
+ 
+       /**
+        * @param string
+        */
+       private void createUniqueModule(String string) {
+ 
+               // // add the main panel to the HTML element with the id 
"stockList"
+               // RootPanel.get("stockList"+string).add(mainPanel);
+ 
+               final StockWatcherPanel swp = new StockWatcherPanel();
+               // add the main panel to the HTML element with the id 
"stockList"
+               RootPanel.get("stockList" + string).add(swp);
+ 
+               // setup timer to refresh list automatically
+               Timer refreshTimer = new Timer() {
+                       public void run() {
+                               swp.refreshWatchList();
+                       }
+               };
+               refreshTimer.scheduleRepeating(REFRESH_INTERVAL);
+ 
+               // move cursor focus to the text box
+               swp.newSymbolTextBox.setFocus(true);
+ 
+       }
+ 
+ }
+ 
+ }}}
+ 
+ 
+  === The StockWatcherComponent ===
+ {{{
+ /*
+  * To change this template, choose Tools | Templates
+  * and open the template in the editor.
+  */
+ 
+ package se.pmdit.tutorial.t5gwt.tapestry.components;
+ 
+ import org.apache.tapestry5.Asset;
+ import org.apache.tapestry5.ComponentResources;
+ import org.apache.tapestry5.RenderSupport;
+ import org.apache.tapestry5.annotations.Environmental;
+ import org.apache.tapestry5.annotations.IncludeJavaScriptLibrary;
+ import org.apache.tapestry5.annotations.Path;
+ import org.apache.tapestry5.annotations.Property;
+ import org.apache.tapestry5.ioc.annotations.Inject;
+ 
+ /**
+  * 
+  * @author djue
+  */
+ 
@IncludeJavaScriptLibrary("context:se.pmdit.tutorial.t5gwt.gwt.StockWatcher/se.pmdit.tutorial.t5gwt.gwt.StockWatcher.nocache.js")
+ public class StockWatcherComponent extends GWTEntryPointComponent {
+       @Environmental
+       private RenderSupport renderSupport;
+       @Inject
+       private ComponentResources resources;
+ 
+       @Inject
+       
@Path("context:se.pmdit.tutorial.t5gwt.gwt.StockWatcher/images/GoogleCode.png")
+       @Property
+       private Asset banner;
+ 
+       void setupRender() {
+               
renderSupport.addScript("GWTComponentController.add('stockwatcher','" + 
resources.getCompleteId() + "')");
+       }
+       // If you wanted you could output the DIV from here, then you would not
+       // need the template file.
+ }
+ }}}
+ 
+ Make special note of this line:
+ 
+ {{{
+ ...
+ renderSupport.addScript("GWTComponentController.add('stockwatcher','" + 
resources.getCompleteId() + "')");
+ ...
+ }}}
+ It's kind of like adding it to a HashMap<String,String>.  (It's not really a 
HashMap, but later your Entrypoint will look up values associated with a key;  
The key will be 'stockwatcher', and the values will be the T5 generated ids)
+ 
+  === The StockWatcherComponent.tml ===
+ Notice the div where the id becomes stockList+component id.  This allows a 
unique and independent stock list to be created.  
+ {{{
+ <div xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";>
+ Stock Watcher Component
+ <div id="${componentResources.completeId}"></div>
+ <img src="${banner}" />
+ <h1>Stock Watcher</h1>
+ <div id="stockList${componentResources.completeId}"></div>
+ </div>
+ }}}
+  Note that this:
+ {{{
+ ...
+ <div id="${componentResources.completeId}"></div>
+ ...
+ }}}
+ Is the same id that you added in the "HashMap" above.
+ 
+ 
+ == General Tips ==
+ 
+ In general it can be very easy to get GWT working with Tapestry.  The 
complexity comes in when you want GWT to be a component, and you consider that 
a component may exist many times on one page.  (think of dialog boxes).  In 
order for the components to behave properly, you must somehow provide a unique 
ID to the Javascript object that GWT will create.
+ 
+ In your GWT code, make the Entrypoint class do as little as possible.  I've 
read this elsewhere as a GWT mini-pattern, but it helps alot here!  Even 
references to your GWT services can be put into the separate class that your 
Entrypoint will instantiate.  In fact the Entrypoints I show here do pretty 
much the same thing:
+  * They load a dictionary and find all the values for a certain "key"
+  * For each value, a new instance of something is created
+ 
+ For example, there will be a String like this:
+ {{{
+ mydialog,mydialog1,mydialog2
+ }}}
+ These are the unique id's that Tapestry will create for you.  Some included 
Javascript (from the other GWT tutorial) will copy these unique id's into a 
Javascript variable.  The compiled GWT Javascript will then read that list of 
id's in your Entrypoint (as shown later)
+ 
+ So instead of having all kinds of code in your entrypoint class, refactor it 
into a separate class that your entrypoint will add to the RootPanel.
+ 
+ == Some unusual things about this ==
+ 
+ The GWT is configured in the POM to output it's compiled directories into 
your src/webapp.
+ (If someone knows a way to use Maven Assembly or an Ant copy that will work 
better, please add it to this wiki)
+ This will require a refresh of your source dir after compilation, or Eclipse 
won't see the GWT compiled code.
+ If Eclipse does not see the new files, then your Tomcat instance won't see it 
either if you are launching Tomcat from Eclipse.
+ 
+ I have not included the gwt compiled directories in the Zip file, because 
they should be generated for you when you run:
+ {{{
+ mvn clean compile gwt:compile
+ }}}
+ 
+ clean will delete the Target directory
+ compile will take care of Java compilation like your T5 code
+ gwt:compile will take care of your GWT generated code (the Javascript)
+ 
+ You could also launch tomcat afterwards using Maven, but I find this less 
thank friendly.
+ 
+ You can leave "Build Automatically" checked in your Eclipse project settings, 
and Tomcat should restart when you make changes on the Tapestry side.  But 
you'll need to restart Tomcat otherwise.
+ 

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to