Publicité

Contenu connexe

Publicité

GWT : under the hood

  1. Google Web Toolkit « Under the hood » Sébastien VUILLET Directeur technique Chez Silverpeas
  2. Plateforme collaborative La réalisation d'un Intranet/Extranet La gestion documentaire (GED) La gestion d'une banque d'images La gestion documentaire de projets La gestion de connaissances Et plus encore ... www.silverpeas.com www.silverpeas.org
  3. Version mobile Power by www.silverpeas.com www.silverpeas.org
  4. État des lieux Le développement d'applications web c'est quoi ? Différents langages : HTML + CSS + JavaScript + Java Différents formats d'échanges : XML, Json ... Différents environnement d’exécution : Desktop, smatphone, tablette Différents moteurs d’exécution : IE, FF, ... Utilisation de langages interprétés
  5. État des lieux Au final développer une webapp ce n'est toujours pas facile !
  6. GWT - Définition Ensemble d'outils Abstraction : du développement JavaScript de l'environnement d’exécution « One to rule them all » Un langage : Java
  7. GWT Masterpiece Le compilateur
  8. GWT - Compilateur Étape Java AST -> Optimized Java AST : Pruning : suppression des classes / interfaces / méthodes / attributs non référencés. Finalizing : rend les méthodes, les classes et les variables final si c'est possible. Make Static : rend statiques les méthodes d'instances si possible (pas de surcharge, n'utilise pas de variables d'instance).
  9. GWT - Compilateur Étape Java AST -> Optimized Java AST : Type Tightening : optimisation des attributs et paramètres pour les rendre concrets (pour réduire les opérateurs cast et instanceof). Method Call Tightening : changement des appels de méthodes polymorphiques, en appel direct. Dead Code Elimination : suppression des portions de code qui n'est jamais appelé (condition jamais
  10. GWT - Compilateur Étape Java AST -> Optimized Java AST : Method Inlining : suppression des méthodes non référencés dans une classe extérieure et embarquement du code directement dans à l'endroit de l'appel (si la méthode n’excède pas deux lignes). Same Parameter Value Optimizer Enum Ordinalizer : remplace les références aux
  11. GWT - Compilateur Étape Java AST -> Optimized Java AST : Remove Empty Super Calls Set of Normalization Rules : transformation du code pour que la génération du JavaScript soit optimale (fusion des blocs catch, utilisation d'array). Remplacement des appels aux classes du JDK par de les classes de com.google.gwt.lang.
  12. GWT - Compilateur Étape Java AST -> Optimized Java AST : arbre « unifié », car il n'est lié à aucune permutation
  13. GWT – Compilateur Les permutations Télécharge uniquement la version nécessaire au navigateur client Un seul code Java … puis le met en cache indéfiniment
  14. GWT - Compilateur Possibilité de désactiver les optimisations : Paramètre : -draftCompile Réglage du code généré : Paramètre : -style (OBF, PRETTY, DETAILED) Amélioration des temps de compilation : Paramètre : -localWorkers Limiter les permutations : <set-property name="user.agent" value="gecko"/>
  15. GWT - Compilateur Code généré par défaut : function qH(){return np} function mH(){} _=mH.prototype=new mu;_.gC=qH;_.tI=0;function uH(){uH=ZH;sH={};tH=[];sH[LM]=[Is,Hs,Js];sH[JM]=[rt,qt,st];Xv(tH,yn,LM);Xv(tH,To,JM)} var sH,tH;function AH(a){a.b=oH(new mH);return a} function BH(a){var b,c,d,e,f,g,h,i,j,k;g=ox(new cx,MM);f=OA(new FA);j=XH(new VH,NM,OM);KA(f,j.b+sJ+j.c);pw(g.B,PM,true);Zw(gA(QM),f);Zw(gA(RM),g);f.B.focus() ;k=Jg(f.B,NJ).length;k>0&&JA(f,0,k);c=py(new my);Lf((tf(),c.b.B),SM);c.o=true; b=ox(new cx,TM);b.B.id=UM;i=Py(new Ny);h=Ty(new My);d=UA(new RA);pw(d.B,VM,true); VA(d,Uy(new My,WM));VA(d,i);VA(d,Uy(new My,XM));VA(d,h);d.b=(kz(),jz);VA(d,b); Ax(c.j,d);Mx(c);vw(b,FH(new DH,c,g),(sh(),rh));e=KH(new IH,a,g,f,i,h,c,b); vw(g,e,rh);vw(f,e,(hi(),gi))} function CH(){return rp} function xH(){}
  16. GWT - Compilateur Code généré en style pretty : var $wnd = parent; var $doc = $wnd.document; var $moduleName, $moduleBase; var $strongName = '21B409FCD39529C5A9DB925F7D8D9A95'; var $stats = $wnd.__gwtStatsEvent ? function(a) {return $wnd.__gwtStatsEvent(a);} : null; $stats && $stats({moduleName:'gwtperf',subSystem:'startup',evtGroup: 'moduleStartup',millis:(new Date()).getTime(),type:'moduleEvalStart'}); var _; function nullMethod(){ } function equals(other){ return this === (other == null?null:other); } function getClass_0(){ return Ljava_lang_Object_2_classLit; } function hashCode_0(){ return this.$H || (this.$H = ++sNextHashId); } function toString_0(){ return (this.typeMarker$ == nullMethod || this.typeId$ == 2?this.getClass$():Lcom_google_gwt_core_client_JavaScriptObject_2_classLit) .typeName + '@' + toPowerOfTwoString(this.typeMarker$ == nullMethod || this.typeId$ == 2?this.hashCode$():this.$H || (this.$H = ++sNextHashId), 4); } function Object_0(){ } _ = Object_0.prototype = {}; _.equals$ = equals; _.getClass$ = getClass_0; _.hashCode$ = hashCode_0; _.toString$ = toString_0; _.toString = function(){ return this.toString$(); } ;
  17. GWT - Compilateur Obfuscation VS pretty :
  18. GWT – build
  19. GWT – Deferred binding Le Deferred Binding consiste à effectuer l’insertion de la classe demandée à la compilation et non durant l’exécution du programme. Deux implémentation de Deferred Binding Replacement : une classe est remplacée par une autre sous certaines conditions Generators : les classes qui héritent d’une classe particulière sont générées et remplacées sous certaines conditions
  20. GWT – Deferred binding Replacement : Configuration du module
  21. GWT – Deferred binding Generators : Classes invoquées par le compilateur GWT pour générer l’implémentation d’un classe java Pour la compilation en mode web, l’implémentation générée est directement traduite en Javascript Configuration du module : Créer un générateur
  22. GWT – Linkers Assurent le packaging Exemples de linkers : IframeLinker (défaut) : génère une Iframe cachée XSLinker : produit des fichiers d'extension xs comme <module>-xs.nocache.js (cas des permutations hébergés sur un autre serveur que les pages hôtes). SingleScriptLinker : génère un seul fichier Java- Script pour un module. Il n'existe qu'une seule permutation.
  23. GWT – Linkers Utilisation des linkers : <module> (...) <define-linker name="sso" class="com.google.gwt.core.linker.SingleScriptLinker" /> <define-linker name="std" class="com.google.gwt.core.linker.IFrameLinker" /> <define-linker name="xs" class="com.google.gwt.core.linker.XSLinker" /> <define-linker name="soycReport" class="com.google.gwt.core.linker.SoycReportLinker" /> <define-linker name="symbolMaps" class="com.google.gwt.core.linker.SymbolMapsLinker" / > <add-linker name="std" /> <add-linker name="soycReport" /> <add-linker name="symbolMaps" /> </module>
  24. GWT – Linkers Créer un linker : Créer une classe dérivant de com.google.gwt.core.ext.Linker. Ajouter l'annotation @LinkOrder pour déterminer si le linker doit s'exécuter avant, après ou en remplacement du linker primaire. Le nombre de linkers n'est pas limité, seul le primaire est unique. Définir et ajouter le linker personnalisé dans le fichier de configuration du module (<module>.gwt.xml). Inclure dans le classpath du compilateur le nouveau
  25. GWT – Linkers Exemple de linker : @LinkerOrder(LinkerOrder.Order.POST) public class MyLinker extends AbstractLinker { public String getDescription() { return "MyLinker"; } public ArtifactSet link(TreeLogger logger, LinkerContext context, ArtifactSet artifacts) throws UnableToCompleteException { String artifactList=""; // Récupère la liste de tous les artéfacts ArtifactSet toReturn = new ArtifactSet(artifacts); for (Artifact artifact : toReturn) { // Et trie seulement les fichiers générés if (artifact instanceof EmittedArtifact) { EmittedArtifact fic = (EmittedArtifact) artifact; // Stocke dans une chaîne de caractères le nom du fichier généré artifactList = fic.getPartialPath() + "," + new Date(fic.getLastModified()).toString() + "n" + artifactList ; } } // Ajoute à la liste précédente un nouveau fichier recensant // les artéfacts toReturn.add(emitString(logger, artifactList, "ListFiles.txt")); return toReturn; } }
  26. GWT – runtime
  27. GWT – perfect caching
  28. GWT – code splitting Découpage en fragments JavaScript pour téléchargement à la demande GWT.runAsync(SomeClass.class, new RunAsyncCallback() { // ... callback class's body ... } Séquence <extend-configuration-property name="compiler.splitpoint.initial.sequence" value="com.yourcompany.yourprogram.SomeClass"/> <extend-configuration-property name="compiler.splitpoint.initial.sequence" value="com.yourcompany.yourprogram.AnotherClassClass"/> <extend-configuration-property name="compiler.splitpoint.initial.sequence" value="com.yourcompany.yourprogram.YetAnotherClass"/>
  29. GWT - Architecture
  30. GWT - JRE Emulation Types primitifs Annotations Exception Assertion Serialization Packages : java.lang java.math java.io
  31. GWT - JRE Emulation Non supporté Multithreading (pour l'instant) Gestion de la concurrence (pour l'instant) Finalisation des objets Réflexion
  32. GWT - JRE Emulation Étendre la JRE Emulation : Ex : Timestamp <module> ... <!-- JRE Classes not Emulated by GWT --> <super-source path='jre'/> </module> Serializer : Timestamp_CustomFieldSerializer public static void serialize(SerializationStreamWriter streamWriter, MyObject myObject) throws SerializationException {} public static void deserialize(SerializationStreamReader streamReader, MyObject myObject) throws SerializationException {} //This method is optional public static MyObject instantiate(SerializationStreamReader streamReader) throws SerializationException {}
  33. GWT - tools Environnement de développement Google plugin pour Eclipse, GWT Designer Debug dans Eclipse avec dev mode et les plugins navigateurs Optimisation SpeedTracer, Soyc Build Maven plugin Tests HtmlUnit, Selenium,...
  34. GWT - synthèse Pas un framework : beaucoup plus gwt-user.jar Le Framework gwt-dev-[platform].jar Les outils
  35. GWT - performances
  36. GWT - performances Client Bundle CSS resources Image resources Data resources Text resources
  37. GWT - performances Client Bundle public interface MyResources extends ClientBundle { public static final MyResources INSTANCE = GWT.create(MyResources.class); @Source("my.css") public CssResource css(); @Source("config.xml") public TextResource initialConfiguration(); @Source("manual.pdf") public DataResource ownersManual(); @Source("default.txt") public TextResource defaultText(); } I18N compatible
  38. GWT - performances Client Bundle : image resources interface Resources extends ClientBundle { @Source("logo.png") ImageResource logo(); @Source("arrow.png") @ImageOptions(flipRtl = true) ImageResource pointer(); } Resources resources = GWT.create(Resources.class); Image img = new Image(resources.logo());
  39. GWT - performances Client Bundle : image resources
  40. GWT - performances Chargement des images sans Client Bundle
  41. GWT - performances Client Bundle : CSS ressources interface MyResources extends CssResource { String myStyleName(); } Fonctionnalités Constantes @def small 1px; @def black #000; border: small solid black; Substitution au runtime @eval userBackground com.module.UserPreferences.getUserBackground(); div { background: userBackground; }
  42. GWT - performances Client Bundle : CSS ressources interface MyResources extends CssResource { String myStyleName(); } Fonctionnalités Constantes @def small 1px; @def black #000; border: small solid black; Substitution au runtime @eval userBackground com.module.UserPreferences.getUserBackground(); div { background: userBackground; }
  43. GWT - performances Client Bundle : CSS ressources Fonctionnalités Value function .myDiv { offset-left: value('imageResource.getWidth', 'px'); } Literal function div-with-literal { top: literal("expression(document.compatMode=="CSS1Compat" ? documentElement.scrollTop : document.body.scrollTop 2)"); }
  44. GWT - performances Client Bundle : CSS ressources Fonctionnalités /* Runtime evaluation in a static context */ Conditions @if (com.module.Foo.staticBooleanFunction()) { ... css rules ... } /* Compile-time evaluation */ @if <deferred-binding-property> <space-separated list of values> { ... css rules ... } @if user.agent safari gecko1_8 { ... } @if locale en { ... } /* Negation is supported */ @if !user.agent ie6 opera { } /* Chaining is also supported */ @if (true) { } @elif (false) { } @else { }
  45. GWT - performances Client Bundle : CSS ressources Fonctionnalités Images sprites public interface DocumentsResources extends ClientBundle { @Source("documents.css") DocumentsCSS css(); @Source("instances.png") ImageResource instances(); } public interface DocumentsCSS extends CssResource { String instances(); } @sprite .instances { gwt-image: "instances"; border: none; }
  46. GWT – Bilan de l'approche Perfect caching Client Bundle Data : URLs & MHTML packaging Developer guided code splitting
  47. GWT - Développements JSNI <=> JNI Ouverture et intégration Fonctionnalités Invoquer du JavaScript natif depuis du code Java public static native void alert(String msg) /*-{ $wnd.alert(msg); }-*/;
  48. GWT - Développements JSNI Invoquez une méthode Java depuis du code javaScript externe //La fonction Java qu'on peut appeler depuis javaScript public static int maFonctionJava(int param) { ... } public static native void exportationMaFonction() /*-{ //On assigne notre méthode // à la variable globale maFonctionJava de notre objet window $wnd.maFonctionJava = $entry(@com.silverpeas.jsni.client::maFonctionJava(I)); }-*/
  49. GWT - Développements Communication avec le serveur Plusieurs approches : RequestBuilder + JSONParser (resty-gwt) RequestBuilder + XMLParser GWT-RPC RequestFactory (depuis GWT 2.1)
  50. GWT - Développements Communication avec le serveur GWT-RPC @RemoteServiceRelativePath("Contact") public interface ServiceContact extends RemoteService { List<DetailUserDTO> getAllContact() throws ContactException; } public class ServiceContactImpl extends AbstractAuthenticateService implements ServiceContact { public List<DetailUserDTO> getAllContact() throws ContactException { ... } }
  51. GWT - Développements Communication avec le serveur GWT-RPC public interface ServiceContactAsync { void getAllContact(AsyncCallback<List<DetailUserDTO>> callback); } web.xml <servlet> <servlet-name>serviceContactImpl</servlet-name> <servlet-class>com.silverpeas.mobile.server.services.ServiceContactImpl</servlet- class> </servlet> <servlet-mapping> <servlet-name>serviceContactImpl</servlet-name> <url-pattern>/spmobil/Contact</url-pattern> </servlet-mapping>
  52. GWT - Développements Communication avec le serveur GWT-RPC : appel ServiceContactAsync serviceContact = (ServiceContactAsync) GWT.create(ServiceContact.class); serviceContact.getAllContact(new AsyncCallback<List<DetailUserDTO>>() { @Override public void onFailure(Throwable caught) { ... } @Override public void onSuccess(List<DetailUserDTO> result) { ... } });
  53. GWT - Développements Communication avec le serveur GWT-RPC : architecture
  54. GWT - Développements Communication avec le serveur GWT-RPC : Simple et puissant Envoie / réception de POJO Support du polymorphisme Transfert optimisés (plus léger que JSON) Sécurité (pas de risque de JavaScript hijacking/JSON attack)
  55. GWT - Développements Communication avec le serveur RequestFactory Pour les services orientés données Niveau d’abstraction plus important que GWT-RPC Plus rapide que GWT-RPC Basé sur JSON : pas de sérialisation/déserialisation Envoi uniquement du différentiel de données Réponse aux problèmes Entity / DTO
  56. GWT - Développements Communication avec le serveur RequestFactory : Entity proxies @Entity public class Employee { @ProxyFor(Employee.class) public interface EmployeeProxy @Size(min = 3, max = 30) extends EntityProxy { private String userName; Long getId(); @Id private Long id; String getUserName(); @Version void setUserName(String userName); private Integer version; ... ... } }
  57. GWT - Développements Communication avec le serveur RequestFactory : Value proxies public interface AddressProxy extends ValueProxy public class Address { { private String street1; public String getStreet1(); private String street2; public String getStreet2(); private String city; public String getCity(); private String st; public String getSt(); private String zip; public String getZip(); ... ... } }
  58. GWT - Développements Communication avec le serveur RequestFactory public interface ExpensesRequestFactory extends RequestFactory { EmployeeRequest employeeRequest(); ... } @Service(Employee.class) public interface EmployeeRequest extends RequestContext { Request<Long> countEmployees(); Request<List<EmployeeProxy>> findAllEmployees(); Request<EmployeeProxy> findEmployee(Long id); InstanceRequest<EmployeeProxy, Void> persist(); InstanceRequest<EmployeeProxy, Void> remove(); }
  59. GWT - Développements Communication avec le serveur RequestFactory final EventBus eventBus = new SimpleEventBus(); requestFactory = GWT.create(ExpensesRequestFactory.class); requestFactory.initialize(eventBus); requestFactory.employeeRequest().findEmployee(employeeId).fire( new Receiver<EmployeeProxy>() { @Override public void onSuccess(EmployeeProxy employee) { ... } }); EmployeeRequest request = requestFactory.employeeRequest(); EmployeeProxy newEmployee = request.create(EmployeeProxy.class); newEmployee.setDisplayName(...); newEmployee.setDepartment(...); ... Request<Void> createReq = request.persist().using(newEmployee);
  60. GWT - Développements Communication avec le serveur RequestFactory : entity validation JSR 303 support Envoi de violation de contraintes au client Appel de la méthode onViolation() du Receiver
  61. GWT - Développements Des logs dans le browser GWT logging # Dans le fichier .gwt.xml <inherits name="com.google.gwt.logging.Logging"/> Logger logger = Logger.getLogger("monLogger"); logger.log(Level.SEVERE, "impossible de contacter le serveur");
  62. GWT - Développements Des logs dans le browser GWT logging : loggers private static Logger childLogger = Logger.getLogger("ParentLogger.Child"); private static Logger parentLogger = Logger.getLogger("ParentLogger"); private static Logger rootLogger = Logger.getLogger(""); Configuration <set-property name="gwt.logging.logLevel" value="SEVERE"/> <set-property name="gwt.logging.enabled" value="FALSE"/> <set-property name="gwt.logging.consoleHandler" value="DISABLED"/>
  63. GWT - Développements Des logs dans le browser GWT logging : handlers SystemLogHandler : stdout (seulement en DevMode) DevelopmentModeLogHandler : sur appel de la méthode GWT.log (seulement en DevMode) ConsoleLogHandler : javascript console FirebugLogHandler : firebug PopupLogHandler : popup SimpleRemoteLogHandler : envoi au serveur (via GWT- RPC)
  64. GWT - Développements Et la GUI ?
  65. GWT - Développements Approche de développement par composants En java : « comme Swing » Widgets et placement par Panels et Layouts Avantages : abstraction de l'html / javascript (DOM/event/memory) programmation événementielle refactoring Inconvénients :
  66. GWT - Développements Les widgets Intégrés : com.google.gwt.user.client.ui
  67. GWT - Développements Les widgets Bibliothèques additionnelles gwt-mosaic Sencha GXT Smartgwt (wrapper) Gwtmobile Gwt-links Gwt-cal GwtGL
  68. GWT - Développements Les widgets Construire ses propres widgets Trois possibilités pour créer ses propres composants : Créer un widget avec des widgets existants Héritage de com.google.gwt.user.client.ui.Composite Créer un widget nouveau sans composition Héritage de com.google.gwt.user.client.ui.Widget Créér un widget qui « wrap » du code JavaScript en utilisation using JSNI
  69. GWT - Développements Les widgets : construire ses propres widgets public class OptionalTextBox extends Composite implements ClickHandler { private TextBox textBox = new TextBox(); private CheckBox checkBox = new CheckBox(); public OptionalTextBox(String caption) { VerticalPanel panel = new VerticalPanel(); panel.add(checkBox); panel.add(textBox); checkBox.setText(caption); checkBox.setChecked(true); checkBox.addClickHandler(this); } public void onClick(ClickEvent event) { Object sender = event.getSource(); if (sender == checkBox) { textBox.setEnabled(checkBox.isChecked()); } } }
  70. GWT - Développements Les widgets : construire ses propres widgets public class OptionalTextBox extends Composite implements ClickHandler { private TextBox textBox = new TextBox(); private CheckBox checkBox = new CheckBox(); public OptionalTextBox(String caption) { VerticalPanel panel = new VerticalPanel(); panel.add(checkBox); panel.add(textBox); checkBox.setText(caption); checkBox.setChecked(true); checkBox.addClickHandler(this); } public void onClick(ClickEvent event) { Object sender = event.getSource(); if (sender == checkBox) { textBox.setEnabled(checkBox.isChecked()); } } }
  71. GWT - Développements Ui-binder (depuis GWT 2.0) : declarative UI Description des vues en XML Binding XML (*.ui.xml) / Java (*.java) <ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'> <g:HTMLPanel> Gagnant, <g:ListBox ui:field='listBox' visibleItemCount='1'/>. </g:HTMLPanel> </ui:UiBinder>
  72. GWT - Développements Ui-binder (depuis GWT 2.0) : declarative UI public class HelloWidgetWorld extends Composite { interface MyUiBinder extends UiBinder<Widget, HelloWidgetWorld> {} private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class); @UiField ListBox listBox; public HelloWidgetWorld(String... names) { // sets listBox initWidget(uiBinder.createAndBindUi(this)); for (String name : names) { listBox.addItem(name); } } }
  73. GWT - Développements Ui-binder (depuis GWT 2.0) : declarative UI Annotations @UiField @UiHandler @UiFactory @UiConstructor @UiTemplate("mobile.ui.xml") Ressources externes <ui:with field='res' type='com.silverpeas.ged.Resources'/> @UiField(provided = true)
  74. GWT - Développements Editors (depuis GWT 2.1) <inherits name="com.google.gwt.editor.Editor" /> POJO Editor (généralement un widget) Driver SimpleBeanEditorDriver RequestFactoryEditorDriver Adapter
  75. GWT - Développements Editors public class PersonEditor extends Composite implements Editor<Person> { interface Binder extends UiBinder<Widget, PersonEditor> {} private static final Binder BINDER = GWT.create(Binder.class); @UiField TextBox firstName; @UiField TextBox lastName; @UiField AddressEditor address; public PersonEditor() { initWidget(BINDER.createAndBindUi(this)); } } Annotations @path et @ignored
  76. GWT - Développements Editors public class PersonView extends Composite { interface Binder extends UiBinder<Widget, PersonView> {} interface EditorDriver extends SimpleBeanEditorDriver<Person, PersonEditor> {} private final Binder BINDER = GWT.Create(Binder.class); private final PersonServiceAsync RPC = GWT.create(PersonService.class); private final EditorDriver editorDriver = GWT.create(EditorDriver.class); @UiField PersonEditor editor; @UiField Button save; @UiField Button cancel; public PersonView() { initWidget(BINDER.createAndBindUi(this)); }
  77. GWT - Développements Editors public void edit(String id) { RPC.getPerson(id, new AsyncCallback<Person>() { @Override public void onSuccess(Person person) { editorDriver.edit(person); } @Override public void onFailure(Throwable e) { ... } }); }
  78. GWT - Développements Editors @UiHandler("save") void onSaveClick(ClickEvent event) { If (! editorDriver.hasErrors()) { Person person = editorDriver.flush(); RPC.savePerson(this.value, new AsyncCallback<Void>() { @Override public void onSuccess(Person person) { ... } @Override public void onFailure(Throwable e) { ... } }); } else { List<EditorError> errors = editorDriver.getErrors() ; ... } } }
  79. GWT - Développements HTML5 (depuis GWT 2.3) Intégration progressive Événements multi-touch Drag & drop LocalStorage & SessionStorage Canvas Audio (expérimentale) Vidéo (expérimentale)
  80. GWT - Développements Patterns MVC : implémentation PureMVC
  81. GWT - Développements Patterns EventBus SimpleEventBus ResettableEventBus CountingEventBus
  82. GWT - Développements Patterns EventBus : handler public interface DocumentsControllerEventHandler extends EventHandler { void loadSettings(DocumentsLoadSettingsEvent event); void saveSettings(DocumentsSaveSettingsEvent event); void loadTopics(DocumentsLoadTopicsEvent event); void loadPublications(DocumentsLoadPublicationsEvent event); void loadPublication(DocumentsLoadPublicationEvent event); }
  83. GWT - Développements Patterns EventBus : event public abstract class AbstractDocumentsControllerEvent extends GwtEvent<DocumentsControllerEventHandler> { public static Type<DocumentsControllerEventHandler> TYPE = new Type<DocumentsControllerEventHandler>(); public AbstractDocumentsControllerEvent() { } @Override public GwtEvent.Type<DocumentsControllerEventHandler> getAssociatedType() { return TYPE; } }
  84. GWT - Développements Patterns EventBus : event public class DocumentsSaveSettingsEvent extends AbstractDocumentsControllerEvent { private ApplicationInstanceDTO instance; private TopicDTO topic; public DocumentsSaveSettingsEvent(ApplicationInstanceDTO instance, TopicDTO topic) { super(); this.instance = instance; this.topic = topic; } @Override protected void dispatch(DocumentsControllerEventHandler handler) { handler.saveSettings(this); } public ApplicationInstanceDTO getInstance() { return instance; } public TopicDTO getTopic() { return topic; } }
  85. GWT - Développements Patterns EventBus Abonnement EventBus.getInstance().addHandler(AbstractDocumentsControllerEvent.TYPE, this); Désabonnement EventBus.getInstance().removeHandler(AbstractDocumentsControllerEvent.TYPE, this); Lancement EventBus.getInstance().fireEvent( new DocumentsSaveSettingsEvent(currentInstance, currentTopic));
  86. GWT - Développements Patterns MVP : intégré depuis GWT 2.1
  87. GWT - Développements Patterns MVP : navigation public class AppActivityMapper implements ActivityMapper { private ClientFactory clientFactory; public AppActivityMapper(ClientFactory clientFactory) { super(); this.clientFactory = clientFactory; } @Override public Activity getActivity(Place place) { if (place instanceof HelloPlace) return new HelloActivity((HelloPlace) place, clientFactory); else if (place instanceof GoodbyePlace) return new GoodbyeActivity((GoodbyePlace) place, clientFactory); return null; } }
  88. GWT - Développements Des APIs pour aller plus loin Internationalisation Sécurité Accessibilité Tests ...
  89. GWT - Développements Des bibliothèques pour aller plus loin Gin : injection client-side Gwt-ent : AOP, Reflexion, ... Gwt-dnd Gwt-comet Crypto-gwt Gwt-voices Gquery
  90. Uses cases Application web single page Caractéristiques : Non server-centric Webapp légère : un conteneur de servlets suffit pas de compilation des pages par le serveur d'applications Application ou site web multi page Caractéristiques : Server-centric : jsp, jsf, php, html Frameworks additionnels : vaadin Application dans le cloud
  91. Qui utilise GWT ?
  92. Que s'est il passé depuis 2006 ? Novembre 2011 : Abandon de flex par adobe Abandon de Silverlight par Microsoft HTML5 plébiscité par le ténors du web
  93. Que s'est il passé depuis 2006 ? Adoption massive des smartphones Explosion des applications mobiles natives
  94. La suite : GWT 2.5 Amélioration du noyau : Optimisation du compilateur : 30 % de réduction du code non compressé et 15 % avec compression gzip Support de SourceMap et Source-Level : java debugging dans Chrome (Firefox à venir)
  95. Futur...
  96. Merci de votre attention

Notes de l'éditeur

  1. Le modèle de développement d&apos;applications à énormément évolué depuis une décennie. Les technologies web se sont imposées et ont évoluées. Les applications web offrent de plus en plus de services, elles sont de plus en plus ergonomiques et performantes. Mais qu&apos;en est-il du quotidien du développeur ? Les outils de développement ont-ils évolués ? Il y a 6 ans l&apos;ovni GWT faisait son apparition, avec pour objectif de facilité le développement d&apos;applications web sophistiqués La vision révolutionnaire de ses deux concepteurs a mit du temps a être accepté. De nos jours comment a évolué GWT ? Qui l&apos;utilise ? La vision de Bruce Johnson et de Joel Webber a-t-elle supporté l&apos;épreuve du temps ? Cette présentation tentera de répondre à ces questions, en présentant ce que GWT a dans le ventre.
Publicité