Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
<ul><ul><li># 3 </li></ul></ul><ul><ul><li>personalization </li></ul></ul><ul><ul><li>and customization. </li></ul></ul>
identify yourself with the product ...
the barmaid remembering your favourite drink ...
customize your drink at Starbucks ...
+6.6 billion people can’t all be the same ...
+/- 191 currencies ...
let’s meet on 01/02/2008 ...
can you pick me up at 9 o’clock ...
<ul><ul><li>annoying. </li></ul></ul><ul><ul><li>my favourite application doesn’t run in an OpenSocial container nor on my...
<ul><ul><li>linker. </li></ul></ul><ul><ul><li>[ overview ] </li></ul></ul>
<ul><ul><li>linker. </li></ul></ul><ul><ul><li>“ In computer science, a linker is a program that takes one or more objects...
object object object iPhone Adobe Air Android Gears Open Social linker
<ul><ul><li>PRIMARY LINKERS </li></ul></ul><ul><ul><ul><li>the primary linker is responsible for module bootstrap </li></u...
<ul><ul><li>ENABLE AN EXISTING LINKER </li></ul></ul><ul><ul><ul><li><add-linker name=“ std ”/>  IFrame linker </li></ul><...
<ul><ul><li>ARTIFACTS </li></ul></ul><ul><ul><ul><li>Linker operate on a set of Artifacts: </li></ul></ul></ul><ul><ul><ul...
<ul><ul><li>linker. </li></ul></ul><ul><ul><li>[ build your own linker ] </li></ul></ul>
<ul><ul><li>customize. </li></ul></ul><ul><ul><li>synthesize additional output-dependent files </li></ul></ul><ul><ul><li>...
<ul><ul><li>BUILD YOUR OWN LINKER (1/2) </li></ul></ul><ul><ul><ul><li>@LinkerOrder(Order.POST) </li></ul></ul></ul><ul><u...
<ul><ul><li>BUILD YOUR OWN LINKER (2/2) </li></ul></ul><ul><ul><ul><li>public Artifact  createFileListArtifact (ArtifactSe...
<ul><ul><li>DEFINE THE NEW LINKER </li></ul></ul><ul><ul><ul><li><define-linker name=“fileListLinker&quot; class=“com.File...
 
<ul><ul><li>linker. </li></ul></ul><ul><ul><li>[ advanced use case ] </li></ul></ul>
<ul><ul><li>INLINE SELECTION SCRIPT INTO HOST PAGE (1/2) </li></ul></ul><ul><li>  </li></ul><ul><li>  public ArtifactSet l...
<ul><ul><li>INLINE SELECTION SCRIPT INTO HOST PAGE (2/2) </li></ul></ul><ul><li>  </li></ul><ul><li>  private EmittedArtif...
<ul><ul><li>localization. </li></ul></ul><ul><ul><li>[ for dummies ] </li></ul></ul>
<ul><ul><li>CREATE INTERFACE TO DEFINE TYPE-SAFE TEMPLATES </li></ul></ul><ul><ul><li>  public interface ErrorMessages ext...
<ul><ul><li>ADD LOCALE CHOICES TO A MODULE </li></ul></ul><ul><ul><li>  <module> </li></ul></ul><ul><ul><li>  <inherits na...
<ul><ul><li>CHOOSE A LOCALE AT RUNTIME </li></ul></ul><ul><ul><li>  url based: http://localhost:808/example ?locale=nl </l...
<ul><ul><li>localization. </li></ul></ul><ul><ul><li>[ demystified ] </li></ul></ul>
<ul><ul><li>CODE GENERATION </li></ul></ul><ul><ul><li>  a Java source file is generated for each defined language </li></...
<ul><ul><li>COMPILER OPTIMIZATION </li></ul></ul><ul><ul><li>  MyConstants constants = GWT.create(MyConstants.class); </li...
<ul><ul><li>localization. </li></ul></ul><ul><ul><li>[ real life issues ] </li></ul></ul>
<ul><ul><li>DYNAMIC LOCALES </li></ul></ul><ul><ul><li>  locales tend to change   </li></ul></ul><ul><ul><li>  many use ca...
<ul><ul><li>DYNAMIC LOCALES </li></ul></ul><ul><ul><li>  runtime locales in the client </li></ul></ul><ul><ul><li>  Label ...
<ul><ul><li>MAARTENVOLDERS. com </li></ul></ul><ul><ul><li>PASSIONATE ABOUT PEOPLE AND TECHNOLOGY </li></ul></ul>
Upcoming SlideShare
Loading in …5
×

GWT@Jazoon08 - Part 3/6 - Personalization & Customization

1,567 views

Published on

A presentation about GWT which I presentaed at Jazoon '08
Part 3/6 - Personalization and Customization

  • Be the first to comment

GWT@Jazoon08 - Part 3/6 - Personalization & Customization

  1. 1. <ul><ul><li># 3 </li></ul></ul><ul><ul><li>personalization </li></ul></ul><ul><ul><li>and customization. </li></ul></ul>
  2. 2. identify yourself with the product ...
  3. 3. the barmaid remembering your favourite drink ...
  4. 4. customize your drink at Starbucks ...
  5. 5. +6.6 billion people can’t all be the same ...
  6. 6. +/- 191 currencies ...
  7. 7. let’s meet on 01/02/2008 ...
  8. 8. can you pick me up at 9 o’clock ...
  9. 9. <ul><ul><li>annoying. </li></ul></ul><ul><ul><li>my favourite application doesn’t run in an OpenSocial container nor on my IPhone nor does it have offline access  </li></ul></ul>
  10. 10. <ul><ul><li>linker. </li></ul></ul><ul><ul><li>[ overview ] </li></ul></ul>
  11. 11. <ul><ul><li>linker. </li></ul></ul><ul><ul><li>“ In computer science, a linker is a program that takes one or more objects generated by the compiler and assembles them into a single executable program.” </li></ul></ul><ul><ul><li>- Wikipedia </li></ul></ul>
  12. 12. object object object iPhone Adobe Air Android Gears Open Social linker
  13. 13. <ul><ul><li>PRIMARY LINKERS </li></ul></ul><ul><ul><ul><li>the primary linker is responsible for module bootstrap </li></ul></ul></ul><ul><ul><ul><li>pre- and post-linkers run before and after the primary Linker </li></ul></ul></ul><ul><ul><ul><li>linkers are only run during web-mode compile </li></ul></ul></ul><ul><ul><ul><li>SelectionScriptLinker // Bootstrap is an external script </li></ul></ul></ul><ul><ul><ul><li> HostedModeLinker // Only for hosted mode </li></ul></ul></ul><ul><ul><ul><li> XSLinker // Cross site linker </li></ul></ul></ul><ul><ul><ul><li> SingleScriptLinker // Provides single JS file </li></ul></ul></ul><ul><ul><ul><li> IFrameLinker [default] // Loads JS in Iframe </li></ul></ul></ul><ul><ul><ul><li>@LinkerOrder( Order.PRIMARY ) </li></ul></ul></ul><ul><ul><ul><li>public class IFrameLinker extends SelectionScriptLinker { … } </li></ul></ul></ul>
  14. 14. <ul><ul><li>ENABLE AN EXISTING LINKER </li></ul></ul><ul><ul><ul><li><add-linker name=“ std ”/> IFrame linker </li></ul></ul></ul><ul><ul><ul><li><add-linker name=“ xs ”/> Cross site linker </li></ul></ul></ul><ul><ul><ul><li><add-linker name=“ sso ”/> Single script linker </li></ul></ul></ul>
  15. 15. <ul><ul><li>ARTIFACTS </li></ul></ul><ul><ul><ul><li>Linker operate on a set of Artifacts: </li></ul></ul></ul><ul><ul><ul><li> CompilationResult // unique chunk of JavaScript permutation </li></ul></ul></ul><ul><ul><ul><li> EmittedArtifact // emitted to output directory </li></ul></ul></ul><ul><ul><ul><li> GeneratedSource // GeneratorContext.tryCreateResource </li></ul></ul></ul><ul><ul><ul><li> PublicResource // files in public path </li></ul></ul></ul><ul><ul><ul><li> SyntheticArtifact // created by Linker </li></ul></ul></ul><ul><ul><ul><li> ScriptReference // external script ref. in .gwt.xml </li></ul></ul></ul><ul><ul><ul><li> StylesheetReference // external CSS ref. in .gwt.xml </li></ul></ul></ul><ul><ul><ul><li>Communicate with Linker stack via GeneratorContext.commitArtifact(); </li></ul></ul></ul><ul><ul><ul><li>Linkers can transform one ArtifactSet into another </li></ul></ul></ul><ul><ul><ul><li>LinkerContext contains global data (module name, selection properties…) </li></ul></ul></ul>
  16. 16. <ul><ul><li>linker. </li></ul></ul><ul><ul><li>[ build your own linker ] </li></ul></ul>
  17. 17. <ul><ul><li>customize. </li></ul></ul><ul><ul><li>synthesize additional output-dependent files </li></ul></ul><ul><ul><li>Google Gears ManagedResourceStore manifest file </li></ul></ul><ul><ul><li>integrate with other environments </li></ul></ul><ul><ul><li>iGoogle, OpenSocial … </li></ul></ul><ul><ul><li>provide an alternate bootstrap or packaging </li></ul></ul><ul><ul><li>Gadgets and single stage bootstraps </li></ul></ul><ul><ul><li>generally solve “GWT and … “ integration </li></ul></ul>
  18. 18. <ul><ul><li>BUILD YOUR OWN LINKER (1/2) </li></ul></ul><ul><ul><ul><li>@LinkerOrder(Order.POST) </li></ul></ul></ul><ul><ul><ul><li>public class FileListLinker extends AbstractLinker { </li></ul></ul></ul><ul><ul><ul><li> public ArtifactSet link (TreeLogger logger, LinkerContext context, </li></ul></ul></ul><ul><ul><ul><li>ArtifactSet artifacts) throws UnableToCompleteException { </li></ul></ul></ul><ul><ul><ul><li> </li></ul></ul></ul><ul><ul><ul><li> ArtifactSet toReturn = new ArtifactSet(artifacts); </li></ul></ul></ul><ul><ul><ul><li> toReturn.add( createFileListArtifact (toReturn)); </li></ul></ul></ul><ul><ul><ul><li> return toReturn; </li></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul>
  19. 19. <ul><ul><li>BUILD YOUR OWN LINKER (2/2) </li></ul></ul><ul><ul><ul><li>public Artifact createFileListArtifact (ArtifactSet toReturn) { </li></ul></ul></ul><ul><ul><ul><li> SortedSet<EmittedArtifact> emitted = toReturn.find(EmittedArtifact.class) ; </li></ul></ul></ul><ul><ul><ul><li> StringBuffer fileList = new StringBuffer(“<html><body>”); </li></ul></ul></ul><ul><ul><ul><li> for ( EmittedArtifact artifact : emitted) { </li></ul></ul></ul><ul><ul><ul><li> fileList.append(artifact.toString() + “<br/>”); </li></ul></ul></ul><ul><ul><ul><li> } </li></ul></ul></ul><ul><ul><ul><li> fileList.append(“</body></html>”); </li></ul></ul></ul><ul><ul><ul><li> return emitBytes(logger, Util.getBytes(fileList.toString()), &quot; fileList.html “)); </li></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul>
  20. 20. <ul><ul><li>DEFINE THE NEW LINKER </li></ul></ul><ul><ul><ul><li><define-linker name=“fileListLinker&quot; class=“com.FileListLinker&quot; /> </li></ul></ul></ul><ul><ul><li>ENABLE THE NEW LINKER </li></ul></ul><ul><ul><li> <add-linker name=“fileListLinker”/> </li></ul></ul>
  21. 22. <ul><ul><li>linker. </li></ul></ul><ul><ul><li>[ advanced use case ] </li></ul></ul>
  22. 23. <ul><ul><li>INLINE SELECTION SCRIPT INTO HOST PAGE (1/2) </li></ul></ul><ul><li> </li></ul><ul><li> public ArtifactSet link(TreeLogger logger, LinkerContext context, </li></ul><ul><li> ArtifactSet artifacts) throws UnableToCompleteException { </li></ul><ul><li> artifacts = new ArtifactSet(artifacts); </li></ul><ul><li> EmittedArtifact script = getSelectionScript (artifacts); </li></ul><ul><li> artifacts. remove (script); </li></ul><ul><li> for (EmittedArtifact e : artifacts.find(EmittedArtifact.class)) { </li></ul><ul><li> if (e.getPartialPath().toLowerCase().endsWith(&quot;.html&quot;)) { </li></ul><ul><li>EmittedArtifact newArtifact = replaceScripts (logger, e, script); </li></ul><ul><li> artifacts. replace (newArtifact); </li></ul><ul><li> } </li></ul><ul><li> } </li></ul><ul><li> return artifacts; </li></ul><ul><li> } </li></ul>
  23. 24. <ul><ul><li>INLINE SELECTION SCRIPT INTO HOST PAGE (2/2) </li></ul></ul><ul><li> </li></ul><ul><li> private EmittedArtifact replaceScript(TreeLogger logger, EmittedArtifact e, </li></ul><ul><li> EmittedArtifact script) throws UnableToCompleteException { </li></ul><ul><li> String page = Util. readStreamAsString (e.getContents(logger)); </li></ul><ul><li> // ... replacements happen ... </li></ul><ul><li> EmittedArtifact toReturn = emitString (logger, page, e.getPartialPath()); </li></ul><ul><li> return toReturn; </li></ul><ul><li> } </li></ul>
  24. 25. <ul><ul><li>localization. </li></ul></ul><ul><ul><li>[ for dummies ] </li></ul></ul>
  25. 26. <ul><ul><li>CREATE INTERFACE TO DEFINE TYPE-SAFE TEMPLATES </li></ul></ul><ul><ul><li> public interface ErrorMessages extends Messages { </li></ul></ul><ul><ul><li> String accessDenied(int code, String userName); </li></ul></ul><ul><ul><li> } </li></ul></ul><ul><ul><li>CREATE CORRESPONDING PROPERTY FILE </li></ul></ul><ul><ul><li> accessDenied=Error {0}: {1} cannot access {2} </li></ul></ul>
  26. 27. <ul><ul><li>ADD LOCALE CHOICES TO A MODULE </li></ul></ul><ul><ul><li> <module> </li></ul></ul><ul><ul><li> <inherits name=“com.google.gwt.i18n.I18N”/> </li></ul></ul><ul><ul><li> <extend-property name=“locale” values=“fr”/> </li></ul></ul><ul><ul><li> </module> </li></ul></ul><ul><ul><li>APPLY MESSAGE </li></ul></ul><ul><ul><li> ErrorMessages msgs = GWT.create(ErrorMessages.class); </li></ul></ul><ul><ul><li> Window.alert(msgs.accessDenied(502, username)); </li></ul></ul>
  27. 28. <ul><ul><li>CHOOSE A LOCALE AT RUNTIME </li></ul></ul><ul><ul><li> url based: http://localhost:808/example ?locale=nl </li></ul></ul><ul><ul><li> meta tag: <meta name=“gwt:property” content=“ locale=fr ”> </li></ul></ul><ul><ul><li>OTHER LOCALE OPTIONS </li></ul></ul><ul><ul><li> messages = templated messages </li></ul></ul><ul><ul><li> constants = simple messages </li></ul></ul><ul><ul><li> withLookup = extra lookup functionality </li></ul></ul><ul><ul><li> dictionary = for locale data encapsulated in the page [runtime] </li></ul></ul><ul><ul><li> </li></ul></ul>
  28. 29. <ul><ul><li>localization. </li></ul></ul><ul><ul><li>[ demystified ] </li></ul></ul>
  29. 30. <ul><ul><li>CODE GENERATION </li></ul></ul><ul><ul><li> a Java source file is generated for each defined language </li></ul></ul><ul><ul><li> generation is based upon the Localizable interface </li></ul></ul><ul><ul><li> </li></ul></ul><ul><ul><li> at runtime a property provider determines the locale based upon </li></ul></ul><ul><ul><li> the ‘ locale=nl ’ URL argument or Meta property </li></ul></ul><ul><ul><li> no data structure in the middle </li></ul></ul><ul><ul><li> no runtime loading or resolution </li></ul></ul><ul><ul><li> they work because they passed the compiler </li></ul></ul><ul><ul><li> format must be UTF-8 </li></ul></ul><ul><ul><li> locale fallback mechanism en_US -> en -> default </li></ul></ul><ul><ul><li> DateTime and NumberFormat have local backend-in </li></ul></ul>
  30. 31. <ul><ul><li>COMPILER OPTIMIZATION </li></ul></ul><ul><ul><li> MyConstants constants = GWT.create(MyConstants.class); </li></ul></ul><ul><ul><li> String hello = constants.hello(); </li></ul></ul><ul><ul><li> Window.alert(hello); </li></ul></ul><ul><ul><li> compiles into: </li></ul></ul><ul><ul><li> $intern_2 = ‘hello’; </li></ul></ul><ul><ul><li> $wnd.alert($intern_2); </li></ul></ul><ul><ul><li> and not into: </li></ul></ul><ul><ul><li> $wnd.alert(‘hello’); // some browsers actually create a new literal object </li></ul></ul>
  31. 32. <ul><ul><li>localization. </li></ul></ul><ul><ul><li>[ real life issues ] </li></ul></ul>
  32. 33. <ul><ul><li>DYNAMIC LOCALES </li></ul></ul><ul><ul><li> locales tend to change </li></ul></ul><ul><ul><li> many use cases include database driven locales </li></ul></ul><ul><ul><li> so how do we deal with runtime changing locales???? </li></ul></ul><ul><ul><li> options </li></ul></ul><ul><ul><li> - locale data stored in project locale files </li></ul></ul><ul><ul><li>  recompile </li></ul></ul><ul><ul><li> - locale data stored in database </li></ul></ul><ul><ul><li>  extract to project locale files + recompile (Thread changes as bugs) </li></ul></ul><ul><ul><li>  reload page + embed new locales in HTML file + Dictionary </li></ul></ul><ul><ul><li>  support runtime locales in the client </li></ul></ul><ul><ul><li> </li></ul></ul>
  33. 34. <ul><ul><li>DYNAMIC LOCALES </li></ul></ul><ul><ul><li> runtime locales in the client </li></ul></ul><ul><ul><li> Label aLabel = new Label(); // HasText </li></ul></ul><ul><ul><li> LocaleSupport.addListener(aLabel); // Updates all HasText on locale change </li></ul></ul><ul><ul><li> there goes the lazy developer .. let’s think … </li></ul></ul><ul><ul><li> But how does the LocaleSupport know that a locale has been updated? </li></ul></ul><ul><ul><li> - server needs to figure out what to do ??? state on the server  </li></ul></ul><ul><ul><li> - poll at regular interval  </li></ul></ul><ul><ul><li> - piggy bagging  </li></ul></ul><ul><ul><li> - do I lock the client while I update all the labels ??? </li></ul></ul><ul><ul><li> - or do I only update the current labels and updates the others later ??? </li></ul></ul><ul><ul><li> - so the client needs to download this complete update mechanism  </li></ul></ul>
  34. 35. <ul><ul><li>MAARTENVOLDERS. com </li></ul></ul><ul><ul><li>PASSIONATE ABOUT PEOPLE AND TECHNOLOGY </li></ul></ul>

×