guit


A next generation gwt framework

Moved to: https://github.com/galdolber/Guit

This framework is all about: * Beautiful code * Simplicity * Convention over configuration * Testability

Release notes

NEXT: early designs and ideas

  • Add events support to presenters
  • Add mocked Style access to presenters
  • Generate a fields access with apt. (@ViewField will still work) ``` //Presenter named Home HomeFields fields;

// Generated from ui.xml class HomeFields { HasText name; // I am not yet sure how we will determine what bindings types will be used HasText password; }

// Home.ui.xml

* GlobalStore: a shared client storage not persistence between refresh's * Add Class<? extends Place> PlaceManager.getCurrentPlace(); * Add server utilities for Places: * PlaceManagerUtil.getToken(Class<? extends Place> placeClass); * PlaceManagerUtil.getToken(Class<? extends Place> placeClass, .... placeData); * Complete the documentation * Creators framework * How to generate a crud * Gwt modules configuration properties * Displays framework * Guit services, Request factory services and Preprocesors * Presenters * Built-in plugins and writing custom plugins * Autofocus * How to write widgets with guit sintax * Editor framework integration * Unit testing * Places * Recipes * How to make your ajax-app predecible: thinking as server side * Navegation menus and how to highlight current place without adding dependencies * Injecting widgets and displaying presenters * Add native support for events under com.google.gwt.view.client. in guits binder * [auto-generate-selenium-stubs](http://groups.google.com/group/google-web-toolkit-contributors/browse_thread/thread/1705ee3e04075b99/fdd52aa7b384d836?lnk=gst&q=Auto+Generating+Selenium+Test+Stubs#fdd52aa7b384d836) * Custom value proxies for non-user-defined classes in request factory generation * We should autodetect when a uibinder ui.xml file has an html root or a widget root * Detect non-serializable types on guit services with apt * Request factory service should support Preprocesors like regural GuitServices * Prevent sending non-user-defined exception to the client in the requestFactory * Crud creator should support RequestFactory * We should generate tests for the generated code of the CreatorsFramework * Support for maven * Editors creator for Collection of enums * Editors creator for relations * Detect the common mistake of using <set-configuration-property name="app.gin.module" -- instead of <extend configuration-property -- * Explore the possibility to use css selectors to bind events (similar to gQuery or even maybe using it) @ViewHandler @CssSelector("table > tr > td") void panel$click() { // Do something } ``` * Add @GuitBinderAnnotation to mark guit binder "magic" fields: driver, factory * When hooking events to elements we need to sink the events * Add Preprocessors support for the entire service * The place manager should support a "modal mode" * Research code-splitting for gwt-rpc * Add app-stats like statistics dashboard for guit logs with stack traces * i18n support for place titles * Add option to generate guitservices stubs to access with requestfactory * TableView panel using presenters and taking advance of guit's view recycling. Similar to the approach used on CocoaTouch TableView

NEXT: on trunk

  • (Thanks to alexander.rud@gmail.com!!!) Multiple views for one presenter: now you can share the same presenter between multiple view files. One permutation can only use one view. Example:
  • Home.java
  • Home.ui.xml // For everyone else
  • IphoneHome.ui.xml
  • AndroidHome.ui.xml
  • IpadHome.ui.xml
  • Settings.java
  • Settings.ui.xml // In this one all permutations use the same view but the iphone
  • IphoneSettings.ui.xml And add this on you module.gwt.xml (the provider is up to you, this example detects mobile devices) <extend-property name="ui.xml.prefix" values="Iphone, Android, Ipad" /> <property-provider name="ui.xml.prefix"><![CDATA[ { var ua = window.navigator.userAgent.toLowerCase(); if (ua.indexOf('android') != -1) { return 'Android'; } if (ua.indexOf('iphone') != -1) { return 'Iphone'; } if (ua.indexOf('ipad') != -1) { return 'Ipad'; } return 'default'; } ]]></property-provider> <set-property name="ui.xml.prefix" value="default"> <none> <when-property-is name="user.agent" value="safari" /> </none> </set-property>

  • All @EventBusHandlers must specify the event class, we still keep the naming convention (this one is to avoid apt conflict on full build)

  • Add apt utils to generate RequestFactory boilerplates ``` // Generates the PersonProxy @HasEntityProxy(service=PersonService.class) public class Person { }

@HasValueProxy public class Range { }

// From this we generates The PersonRequestFactory and PersonRequest @ImplementedBy(PersonServiceImpl.class) public interface PersonService {

Integer countPerson();

Person findPerson(Long id); } * New way of invoking commands @GuitService public interface PersonService { List listPerson(int offset, int limit); }

// Generated public class PersonServiceAsync { AsyncMethod> listPerson(int offset, int limit) { // Bunch of generated code } }

// Usage @Inject PersonServiceAsync s;

// Call s.listPerson(0, 30).fire(new Async>() {

public void success(List<Person> response) {
    // Do your stuff
}

});

* Changing separation symbol of places from | to / * Add RootPanelDisplay and RootLayoutPanelDisplay displays * Adding new display system to manage contrainers on screen From: @GwtPresenter public void Chrome extends ChromePresenter {

@ViewField AcceptsOneWidget center;

@GwtDisplay("CenterDisplay") public void setCenter(IsWidget w) { assertView(); center.setWidget(e); } } We will generate this annotation: @BindingAnnotation @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CenterDisplay { } And this provider: public class CenterDisplayProvider implements Provider { @Inject Chrome owner;

AcceptsOneWidget acceptsOneWidget = new AcceptsOneWidget() { @Override public void setWidget(IsWidget w) { owner.setCenter(w); } };

@Override public AcceptsOneWidget get() { return acceptsOneWidget; } } And this module: public class CenterDisplayModule extends AbstractGinModule {

@Override protected void configure() { bind(AcceptsOneWidget.class).annotatedWith(CenterDisplay.class).toProvider(CenterDisplayProvider.class).in(Singleton.class); } } * Adding void assertView() method to presenters. * No longer necessary to declare binder contributors on the gwt module. Now we auto-detect them * Add new smart newItem to place manager to avoid locks. void newItem(Class> placeClass, D placeData, D defaultPlaceData); * Crud service creator * Slim3 * Objectify * JDO * JPA: this is the only one that wont work out of the box. It @Inject an EntityManager, you'll need to provide it. * Creators infrastructure with custom templates * CellTable creator * Form creator * Crud presenter creator * Autofocus should support Focusable, Widgets and Elements * Add title support for places @GwtPresenter(title="Groups") * Add guice module to easily inject request factory locators * Remove EventBus/EventBusImpl and use the one provided by gwt * Adding GetRpc module to make the rpc transfer using get instead of post method. * Fixing XsRpc module: cross-domain rpc * Join @PlaceName, @Autofocus into @GwtPresenter * Make automatic place names more web-like: UsersList.class -> users\_list * Add easy way of hooking events to elements using the event bubble.

Click me

@ViewHandler void button$click() { // Some work }

@ViewHandler(event=ClickEvent.class, fields="button") void buttonClick() { // Some work } ```

  • Add StopPlace interface that only implements stop() but not mayStop() and stay(), StayPlace will extend this interface
  • Add alternative to move the views(ui.xml) into a "view" sub-package
  • User rpc exceptions should not be logged as SEVERE, but as INFO
  • Use Scheduler for command service batching
  • Add preprocessor support for guit service methods. This should be done by aop, but you don't get injection with aop! ``` public class LoginValidation implements Preprocesor { @Inject LoginHelper loginHelper;

    @Override
    public void run(LoginRequired annotation) { if (!loginHelper.isLogged()) { throw new LoginException(); } } }

@PreprocesorAnnotation(LoginValidator.class) @Retention(RUNTIME) @Target(Method) public @interface LoginRequired { }

@GuitService public interface AdministrationService { ...

@LoginRequired
void destroySystem();

} ``` * When multiple equal actions are sent on the same batch we only send one and distribute the result on the multiple callbacks. * Adding Optimize gwt module with good practices to generate smaller apps.

v1.6 (With support for GWT 2.2)

  • Deleted all deprecated binders and generator
  • AutoFocus support for presenters
  • @ForceEvent to add any event to any widget
  • Provided fields not longer have to be interfaces, this allows to @Inject and @ViewField(provided=true) a field
  • Adding Lazy utility class to provide a single instance
  • Partial support for GWT Designer
  • Better logging messages
  • ForceEvent, ViewFields annotations merged into ViewHandler.
  • Refactor GuitWidget as an alternative to UiBinder without injections (no commandService, eventBus or placeManager). For injection use a presenter and @Inject and @ViewField(provided=true) it.

v1.5

  • Automatic ViewImplementation generation from UiBinder xml.
  • Google analytics place integration.
  • Google analytics user action tracker implementation.
  • ViewField: bind a view field directly into the presenter as an interface. Support for interfaces emulation.
  • New UiBinder like binder(GuitBinder) that will deprecate the current ones.
  • View implementation recycling support.
  • Add @ViewFields annotation to allow a custom handlers methods names.
  • Deferred action execution on CommandService (executeLater) that will batch in the next request.
  • More flexible view initializers with @ViewInitializer methods.
  • Add specific mocking support for Constants in GuitTests.
  • Making GuitPresenter lazy by default.
  • Catch SerializationExceptions on CommandService and provide alerts.
  • APT plugin
    • GuitPresenters validation-> @GwtPresenter, @GwtController and @GwtWidget
    • Code generation of events and actions
    • Easier i18n declaration for uibinder
  • GuitService generator
  • Auto-generate hashCode(), equals and toString of actions
  • Encrypted place token's data
  • Remove all code afected by issue5221 to be able to compile guit into a jar
  • Moving code to com.guit package
  • Optimized RemoteServiceServlet with guit specifics
  • Cross-Site RPC support
  • Update StoryOfYourEvent to use java logging (now supported on gwt 2.1)
  • GuitWidget: The new UiBinder for non-injection situations
  • Client-side caching support for actions
  • Add support for the new Editor framework on GWT 2.1

Get started

One minute scaffold project ( + 1:30 minutes to start hosted mode)

http://www.youtube.com/watch?feature=player_embedded&v=S_u7CkU_NnI' target='_blank'>http://img.youtube.com/vi/S_u7CkU_NnI/0.jpg' width='425' height=344 />

Unit testing with guit

http://www.youtube.com/watch?feature=player_embedded&v=QjJ25A08sOY' target='_blank'>http://img.youtube.com/vi/QjJ25A08sOY/0.jpg' width='425' height=344 />

TODO tutorials:

Presenters, view fields and view handlers

Communicating with the server

Events and the event bus

Cross-site rpc

Good references

http://www.youtube.com/watch?feature=player_embedded&v=PDuhR18-EdM' target='_blank'>http://img.youtube.com/vi/PDuhR18-EdM/0.jpg' width='425' height=344 /> http://www.youtube.com/watch?feature=player_embedded&v=M5x6E6ze1x8' target='_blank'>http://img.youtube.com/vi/M5x6E6ze1x8/0.jpg' width='425' height=344 /> http://www.youtube.com/watch?feature=player_embedded&v=T_CLzgEL7FA' target='_blank'>http://img.youtube.com/vi/T_CLzgEL7FA/0.jpg' width='425' height=344 />

Project Information

Labels:
GWT Guice gin mvp place command testing useraction analytics uibinder ajax