Upload
danrubel
View
2.353
Download
0
Embed Size (px)
Citation preview
Google Confidential and Proprietary
Course materials
All course materials are available on USB flash drive
Copy the following from the USB drive to your computer• Eclipse 3.6.2 (if you don’t already have it)
• gpe-2.3-alpha-eclipse3.6.zip
• gwt-tutorial.zip
Install zipped update sites now to save time in Lab 1
1
Google Confidential and Proprietary 2
GWT App start to finishA hands-on tutorial building GWT using GPE
Presented by:
Rajeev DayalEric ClaybergDan Rubel
Client Logo
Google Confidential and Proprietary
Agenda
Introduction
GPE Overview
Google APIs
Lab 1
GWT Overview
GWT and GPE
Lab 2
Advanced Topics
3
GWT = Google Web Toolkit
GPE = Google Plugin for Eclipse
Google Confidential and Proprietary
Introduction
Rajeev Dayal
4
Eric Clayberg Dan Rubel
Google Confidential and Proprietary
Course materials
All course materials are available on USB flash drive
Copy the following from the USB drive to your computer• Eclipse 3.6.2 (if you don’t already have it)
• gpe-2.3-alpha-eclipse3.6.zip
• gwt-tutorial.zip
Install zipped update sites now to save time in Lab 1
5
Google Confidential and Proprietary
GPE OverviewA brief introduction to Google Plugin for Eclipse
6
Google Confidential and Proprietary
Google Plugin for Eclipse
7
GoogleAPIs
GPE
Google Confidential and Proprietary
Google Plugin for Eclipse
Wizards, Quick Fixes, Launching, Optimization, Deployment
8
Google Confidential and Proprietary
GWT Designer
Robust visual editing of GWT UI code
9
Google Confidential and Proprietary
Development Cycle
10
HitRefresh
QuickTest
WriteCode
Google Confidential and Proprietary
GPE Dev Mode
11
Google Confidential and Proprietary
Debug in GPE Dev Mode
12
Google Confidential and Proprietary
Compile for production
13
Your app running here.No plugins.
Source files:
Code, CSS, Images, Resources, …
GWT Compiler
Google Confidential and Proprietary
Optimize with Speed Tracer
14
Google Confidential and Proprietary
One click deploy to AppEngine
15
Google Confidential and Proprietary
Google APIs OverviewA brief introduction to Google APIs
16
Standard access to Google services
Google Confidential and Proprietary
Google APIs
17
Google Confidential and Proprietary
Google APIs
Standard access to Google services• Templates for expressing data
like JSON, XML, ...
• Flexible calling styles JSON-RPC and REST
• Configurable interceptors for common things authorization, caching, logging, ...
• Auto-generated client libraries Java, Python, JavaScript
18
Google Confidential and Proprietary
Google APIs
http://code.google.com/more/table/
19
Google Confidential and Proprietary
Google APIs
Many APIs available• Ads, Analytics, Apps, Books, Buzz, Calendar, Contacts, ...
http://code.google.com/more/
20
Google Confidential and Proprietary
Google API Documentation
Select an API and explore
21
Google Confidential and Proprietary
Google API Documentation
Documentation
Javadoc
22
http://code.google.com/apis/gdata/javadoc/
Google Confidential and Proprietary
Importing Google APIs
Import an API into your Eclipse project• Click on “Import Google APIs...”
• Select the desired API and click “Finish”
23
Import
GPE
Google Confidential and Proprietary
Google API Documentation (alternate)
Alternate path to documentation• Click on “Import Google APIs...”
• Click “API documentation”
24
GPE
Google Confidential and Proprietary
Book APIs
Java packages
• com.google.gdata.client.books.* BookService VolumeQuery
• com.google.gdata.data.books.* BooksCategory BooksLink BooksNamespace VolumeFeed VolumnEntry ...
25
Code to search book content ...
Google Confidential and Proprietary
Book Search Example
26
• Application name = [company-id]-[app-name]-[app-version]
Google Confidential and Proprietary
Initialize the service
27
• Book search URL
• Search text
• Only return results which have previews available
Google Confidential and Proprietary
Build the query
28
Unique to each service
• Search criteria
• Search result
Google Confidential and Proprietary
Execute the query
29
• Show the result to the user
Google Confidential and Proprietary
Display the result
30
Google Confidential and Proprietary
Other Google API resources
Samples• http://code.google.com/p/gdata-java-client/downloads/list
Other tools• http://code.google.com/apis/explorer/
• http://googlecodesamples.com/oauth_playground/
• http://code.google.com/apis/chart/docs/chart_playground.html
31
Google Confidential and Proprietary 32
Lab 1Command Line Book Search
Google Confidential and Proprietary
Course materials
All course materials are available on USB flash drive
Copy the following from the USB drive to your computer• Eclipse 3.6.2 (if you don’t already have it)
• gpe-2.3-alpha-eclipse3.6.zip
• gwt-tutorial.zip
33
Google Confidential and Proprietary
Installation
Unzip Eclipse 3.6.2
Install GPE 2.3 Alpha• Select “Help > Install New Software”• Click “Add”• Click “Archive”• Locate “gpe-2.3-alpha-eclipse3.6.zip”
Install GWT Tutorial• Repeat for “gwt-tutorial.zip”
Must have network connection
Calculating requirements takes time
34
Google Confidential and Proprietary
Load Lab
Select “Window > Show GWT Tutorial”
Select “Lab 1”
Click “Import” toolbar button
35
Google Confidential and Proprietary
Import Google APIs
Select “BookSearch” project
Click “Import Google APIs” toolbar button
Select “Books” and click “Finish”
36
Google Confidential and Proprietary
Edit Search
public static void main(String[] args) throws Exception { // Get the search text String searchText = "EclipseCon";
if (args != null && args.length > 0) { String firstArg = args[0]; if (firstArg != null) { firstArg = firstArg.trim(); if (firstArg.length() > 0) { searchText = firstArg; } } }
... etc ...
37
Modify the search term
BookSearchCmdLine.java
Google Confidential and Proprietary
Run
Right click on “BookSearchCmdLine” file
Select “Run As > Java Application”
38
Google Confidential and Proprietary 39
GWT OverviewA brief introduction to the Google Web Toolkit
Google Confidential and Proprietary
GWT in 10 seconds
40
AsynchronousJavaScriptAndXML++
Google Confidential and Proprietary
GWT overview
41
Java GWT Compiler
JavaScript(optimized)
Google Confidential and Proprietary
GWT overview
Advantages• Write web apps in Java
• Compiles to optimized JavaScript (small and fast)
• Easy (and efficient) RPC
• Open source compiler
• Cross browser support... just works
42
Plugins
Google Confidential and Proprietary
Can you find the bug?
43
Google Confidential and Proprietary
Catch errors at compile time
44
Google Confidential and Proprietary
Used at Google
45
AdWords, AdSense, Maps, Docs, Groups, ...
Google Confidential and Proprietary
Rich ecosystem
46
Utilities gwt-dnd, gwt-log, gwt-voices, gwt-fx
Mobile gwt-mobile-toolkit
Google Confidential and Proprietary
Rich ecosystem
www.gwtmarketplace.com
47
Google Confidential and Proprietary
GWT UI Gallery
48
Google Confidential and Proprietary
GWT and GPEGWT development with Google Plugin for Eclipse
49
Google Confidential and Proprietary
Creating a new GWT project
Click the “new web application” button and fill in the fields
50
Google Confidential and Proprietary
Importing Google APIs
Select a project and click “Import Google APIs” toolbar button
51
Google Confidential and Proprietary
Project structure
• Client code• Client only code• Restricted library• Java code compiled to JavaScript
• Server code• Server only code• Full Java library
• Shared code• Restricted library• Code available to both client and server
• Google APIs• Server only code
52
Google Confidential and Proprietary
UiBinder
File > New > Other...
53
Google Confidential and Proprietary
UiBinder
Associated source files• SearchPanel.ui.xml - layout
• SearchPanel.java - behavior
54
Google Confidential and Proprietary
UiBinder
55
<ui:UiBinder xmlns:ui="... etc ..."> <g:HTMLPanel width="600px" height="100%"> Please enter a search term: <g:AbsolutePanel width="600px" height="250px"> <g:at left="0" top="0"> <g:TextBox ui:field="searchText" ... >EclipseCon</g:TextBox> </g:at> <g:at left="514" top="0"> <g:Button ui:field="searchButton" ... >Search</g:Button> </g:at> <g:at left="0" top="27"> <g:ListBox ui:field="resultsList" ...="10"/> </g:at> </g:AbsolutePanel> ... etc ...
public class SearchPanel extends Composite { interface SearchPanelUiBinder extends UiBinder<Widget, SearchPanel> { } private static SearchPanelUiBinder uiBinder = GWT.create(SearchPanelUiBinder.class); @UiField TextBox searchText; @UiField Button searchButton; @UiField ListBox resultsList; ... @UiHandler("searchButton") void onSearchButtonClick(ClickEvent event) { search(); }
SearchPanel.ui.xml
SearchPanel.java
Google Confidential and Proprietary
GWT RPC
@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}
search(“some-search-text”)
BookSearchResult
56
Client Server
• Send / receive Plain Old Java Objects (POJO)
• Versioned to help keep client & server in sync
• Serialized, JSON, or XML data formats
Google Confidential and Proprietary
GWT RPC
@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}
public interface BookSearchAsync { void search(String searchText, AsyncCallback<BookSearchResult> callback);}
57
Client
Google Confidential and Proprietary
GWT RPC
@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}
public interface BookSearchAsync { void search(String searchText, AsyncCallback<BookSearchResult> callback);}
58
Client
Google Confidential and Proprietary
GWT RPC
@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}
public interface BookSearchAsync { void search(String searchText, AsyncCallback<BookSearchResult> callback);}
public class SearchPanel extends Composite { private final BookSearchAsync bookSearch = GWT.create(BookSearch.class);}
59
Client
Google Confidential and Proprietary
GWT RPC
@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}
public interface BookSearchAsync { void search(String searchText, AsyncCallback<BookSearchResult> callback);}
public class SearchPanel extends Composite { private final BookSearchAsync bookSearch = GWT.create(BookSearch.class);}
60
Client
Google Confidential and Proprietary
GWT RPC
@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}
public interface BookSearchAsync { void search(String searchText, AsyncCallback<BookSearchResult> callback);}
public class SearchPanel extends Composite { private final BookSearchAsync bookSearch = GWT.create(BookSearch.class);
void search() { bookSearch.search(searchText.getText(), new AsyncCallback<BookSearchResult>() { public void onSuccess(BookSearchResult results) { // show search results } public void onFailure(Throwable caught) // report error to user } }); }}
61
Client
Google Confidential and Proprietary
GWT RPC
@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}
public class BookSearchImpl extends RemoteServiceServlet implements BookSearch {
62
Server
Google Confidential and Proprietary
GWT RPC
@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}
public class BookSearchImpl extends RemoteServiceServlet implements BookSearch {
public BookSearchResult search(String input) {
63
Server
Google Confidential and Proprietary
GWT RPC
@RemoteServiceRelativePath("search")public interface BookSearch extends RemoteService { BookSearchResult search(String searchText);}
public class BookSearchImpl extends RemoteServiceServlet implements BookSearch {
public BookSearchResult search(String input) {
... perform search ... // Return the result BookSearchResult result = new BookSearchResult(); result.setBooks(books.toArray(new Book[books.size()])); return result; }}
64
Server
Google Confidential and Proprietary
Lab 2GWT UI Book Search
65
Google Confidential and Proprietary
Load Lab
Select “Window > Show GWT Tutorial”
Select “Lab 2”
Click “Import” toolbar button
66
Google Confidential and Proprietary
Import Google APIs
Select “BookSearch” project
Click “Import Google APIs” toolbar button
Select “Books” and click “Finish”
67
Google Confidential and Proprietary
Edit UI
Double-click on “SearchPanel.ui.xml”
Click on “Design” tab
68
Google Confidential and Proprietary
Add Event Handler
Right-click on “resultList” widget
Select “Add Event Handler > onDoubleClick”
69
Google Confidential and Proprietary
Event Handler Behavior
Implement the event handler to open a new browser tab showing the content
70
Google Confidential and Proprietary
Event Handler Behavior
UI Element UI Event
@UiHandler("resultsList")void onResultsListDoubleClick(DoubleClickEvent event) { int index = resultsList.getSelectedIndex(); if (index != -1 && currentResults != null) { Book book = currentResults.getBooks()[index]; Window.open(book.getPreviewHref(), "_blank", ""); }}
Open new browser tab Get selected book
71
Google Confidential and Proprietary
Run
Right click on “BookSearch” project
Select “Run As > Web Application”
Opens “Development Mode” view
72
Google Confidential and Proprietary
Run
Double-click on URL in “Development Mode” view
Enter search term
Click “Search” button
73
Google Confidential and Proprietary
Check your work
Select “Lab 2 - GWT Book Search (complete)”
Click “Compare” toolbar button
74
Google Confidential and Proprietary
AdvancedAdvanced GWT Topics
75
Google Confidential and Proprietary
Optimize with Speed Tracer
Hooks in to low-level instrumentation in the browser to provide information about:• paint events
• CSS style recalculation
• layout events
• general DOM events
• network traffic
76
Google Confidential and Proprietary
Optimize with Speed Tracer
Why does such detailed information matter?• UIs are complex, and they take time to lay out - users can tell
• It’s easy to write pathological UI code and not know it
77
// This line invalidates layout.elementA.className = 'foo';
// This line requires layout to be up to date.var aWidth = elementA.offsetWidth;
// Invalidates layout again.elementB.className = 'bar';
// Requires layout to be up to datevar bWidth = elementB.offsetWidth;
Google Confidential and Proprietary
Optimize with Speed Tracer
Instead..
78
// These lines invalidate layout.elementA.className = 'foo';elementB.className = 'bar';
// This line requires layout to be up to date.var aWidth = elementA.offsetWidth;
// Layout is already up to date; nothing to dovar bWidth = elementB.offsetWidth;
Google Confidential and Proprietary
Launch SpeedTracer
From Chrome...
Or from Eclipse...
79
Google Confidential and Proprietary
ClientBundle
Ensures that an application’s resources are perfectly cacheable • the filename of the resource is based on a MD5 hash of the file’s contents
• configure your web server to cache files that match “*.cache.*” until the sun explodes
Reduces HTTP round-trips for resources• inline resources into compiled JS with data:// URLs
80
Without ClientBundle... slow to load
Google Confidential and Proprietary
A Few Resource Types..
TextResource• either intern strings into compiled JavaScript, or place all strings into a single
file that’s fetched at runtime
• @Source(“foo.txt”), textResource.getText()
CssResource • constants
In CSS: @def small 1px; border: small solid black; In Java: cssResource.small()
• conditional CSS compile-time: @if user.agent ie6 opera { // css rules } runtime: @if (com.module.Foo.staticBooleanFunction()) { // css rules }
• runtime substitution @eval userBackground com.module.UserPrefs.getUserBackground(); div
{ background: userBackground; }
• other cool stuff: minification, obfuscation, value functions, image spriting.. 81
Google Confidential and Proprietary
ImageResource in ClientBundle
82
∑ Separate Bundled
20,558 bytes
6,824 bytes
11 separate images
1 bundled image
Google Confidential and Proprietary
Code Splitting
Defer downloading portions of your application
83
public class Hello implements EntryPoint { public void onModuleLoad() { Button b = new Button("Click me", new ClickHandler() { public void onClick(ClickEvent event) {
Window.alert("Hello, AJAX");
} });
RootPanel.get().add(b); }}
Google Confidential and Proprietary
Code Splitting
Defer downloading portions of your application
84
public class Hello implements EntryPoint { public void onModuleLoad() { Button b = new Button("Click me", new ClickHandler() { public void onClick(ClickEvent event) {
Window.alert("Hello, AJAX");
} });
RootPanel.get().add(b); }}
GWT.runAsync(new RunAsyncCallback() { public void onFailure(Throwable caught) { Window.alert("Code download failed"); }
public void onSuccess() {
} });
Google Confidential and Proprietary
Code Splitting
Very powerful tool for ...• reducing your application’s initial download size
• reducing startup time
Splitting your app effectively requires ...• tools - such as the compile report
• iteration - you won’t get it right the first time
85
Google Confidential and Proprietary
Compiler Optimizations
GWT Compiler automatically does...• Shrinking (obfuscation)
• Type tightening
• Dead code removal
• Inlining
• Constant folding
• Common subexpression elimination
86
Google Confidential and Proprietary
Compiler Options
-XdisableClassMetadata• Disables some java.lang.Class methods (e.g. getName())
-XdisableCastChecking• Disables run-time checking of cast operations
87
Google Confidential and Proprietary
RPC “flavors”
• RequestBuilder + JSONParser (see RESTY-GWT)
• RequestBuilder + XMLParser
• GWT-RPC (easiest) Requires Java on the server-side
• RequestFactory Also requires Java on the server-side higher level of abstraction over GWT-RPC only send data from server to client if that data has been modified since the last
request
None of the RPC mechanisms are synchronous!
88
Google Confidential and Proprietary
“Frameworks”
Model-View-Presenter• View: UI and implementation
• Presenter: business logic, formats the data for display in the view, sits between model and view
Activities and Places• Activity (presenter)
• Places (state in the UI, tied to browser history)
• A place is associated with an activity; an activity has an associated view
Cell Widgets• used for displaying large datasets quickly
• display is done using innerHTML instead of DOM manipulation
• data providers; updates to the data source are reflected in the widget
• can also accept input and push changes back to data source89
Google Confidential and Proprietary
Authorization
Need access to a user’s data? You need authorization from them.• Google APIs
Enter OAuth• allows you to write an application that asks a user’s permission to access a
protected resource (i.e. their gmail contacts)
• the user does two things: they first authenticate with the entity that controls the data (i.e. Google) the entity then asks the user if he/she wants to give your application to access a
specific set of your data; the user grants/denies permission
• if the user grants permission, your application receives a notification via a callback URL, along with a token that can be used to access the resource
• a scope is needed this is defined by the entity that controls the data
• your application never actually sees the user’s password!
90
Google Confidential and Proprietary
OAuth
Gotchas with OAuth• “dance”: request token, authorized token, access token
• user authentication with the entity happens in a web browser
• signed requests - the token, sent along with the request, is signed with a key based on the request URL (no curl!)
OAuth 2.0• no signed requests; all requests need to be done over HTTPs
• greatly simplifies the process
• access token and refresh token
91
Google Confidential and Proprietary
OAuth
Resources• Using OAuth 2.0 to Access Google APIs
http://code.google.com/apis/accounts/docs/OAuth2.html
• Using OAuth with the GData APIs http://code.google.com/apis/gdata/articles/oauth.html (these haven’t moved to OAuth 2.0 yet)
• OAuth 1.0 Playground http://googlecodesamples.com/oauth_playground/
• Authentication and Authorization for Google APIs http://code.google.com/apis/accounts/docs/GettingStarted.html
92
Google Confidential and Proprietary
Testing
• use GWTTestCase to test GWT UIs
• use MVP (not MVC) to isolate UI code and maximize testability
Google I/O talk on testing ...• http://www.google.com/events/io/2010/sessions/gwt-continuous-build-testing.html
Testing methodologies ...• http://code.google.com/webtoolkit/articles/testing_methodologies_using_gwt.html
93
MVP
Plugins
MVC
Google Confidential and Proprietary
Questions
?94
?
?
?
Google Confidential and Proprietary
Thank You
Where to get it: http://code.google.com/webtoolkit/
Wiki, issue tracker, source: http://code.google.com/p/google-web-toolkit/
Official GWT blog: http://google-web-toolkit.blogspot.com/
95