SlideShare a Scribd company logo
GDG 2013
MVP GWT application with Spring
    Roo and CloudFoundry


       Ali Parmaksız                         @parmaksiza
                                    ali.parmaksiz@eu.sony.com
       Jan 19, 2013

http://aliparmaksiz.blogspot.com/
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
Agenda
•   MVP Pattern (GWT)
•   Activites & Places (GWT)
•   MongoDb (NoSql)
•   Spring Roo (RAD for Java)
•   CloudFoundry (PAAS)
MVP Pattern GWT
ProxyServiceAsync proxyservice = ProxyService.Util.getInstance();

@UiField LabelElement listLabel;
@UiField Anchor continueButton;
@UiField Anchor backButton;
@UiField SpanElement continueButtonSpan;
@UiField SpanElement backButtonSpan;
@UiField TextBox listName;
@UiField Image listNameGif;
@UiField HTMLPanel createListPanel;
@UiField Validation validationMessages;

private void callServerSideValidation(final String listNameText) {
new RPCCall<ServiceResponse<ResultWithError>>() {
@Override
protected void callService(AsyncCallback<ServiceResponse<ResultWithError>> cb) {
                   proxyservice.createListNameIfValid(listNameText,cb);
                                                 }
@Override
public void onFailure(Throwable caught) {
  System.out.println(caught);
}
@Override
public void onSuccess(ServiceResponse<ResultWithError> result) {
  List<ValidationError> validationErrors = result.getResult().getErrorList();
  pressErrorMessage(validationErrors);                                           if(validationErrors == null
|| validationErrors.size() == 0){
  infoModel.setResult(result.getResult().getServiceResult());
  infoModel.setListName(listNameText);
  PageNavigationReadyEvent event = new
PageNavigationReadyEvent(PageNavigationReadyEvent.BUTTON_DIRECTION_FORWARD,
CreateListResult.class.getName());
  serviceHandlerManager.fireEvent(event);                                        }
                  }                              }.retry(0);                     }
GWT hears you
MVP Pattern(View)
• View
         public class ContactsView extends Composite implements ContactsPresenter.Display {
          private final Button addButton;
          private final Button deleteButton;
          private FlexTable contactsTable;
          private final FlexTable contentTable;
          public ContactsView() {
            DecoratorPanel contentTableDecorator = new DecoratorPanel();
            initWidget(contentTableDecorator);
            contentTableDecorator.setWidth("100%");
            contentTableDecorator.setWidth("18em");
                   ************************
          public void setData(List<String> data) {
             contactsTable.removeAllRows();
             for (int i = 0; i < data.size(); ++i) {
               contactsTable.setWidget(i, 0, new CheckBox());
               contactsTable.setText(i, 1, data.get(i));
            }
         }
MVP Pattern(Presenter)
public class ContactsPresenter implements Presenter {
  private List<ContactDetails> contactDetails;
  public interface Display {
     HasClickHandlers getAddButton();
     HasClickHandlers getDeleteButton();
     HasClickHandlers getList();
     void setData(List<String> data);
     int getClickedRow(ClickEvent event);
     List<Integer> getSelectedRows(); Widget asWidget();
}
  private final ContactsServiceAsync rpcService;
  private final HandlerManager eventBus;
  private final Display display;
MVP Pattern(Presenter)
     private void fetchContactDetails() {
         rpcService.getContactDetails(new AsyncCallback<ArrayList<ContactDetails>>() {
         public void onSuccess(ArrayList<ContactDetails> result) {
             contactDetails = result;
              sortContactDetails();
             List<String> data = new ArrayList<String>();
             for (int i = 0; i < result.size(); ++i) {
                  data.add(contactDetails.get(i).getDisplayName());  }
                  display.setData(data); }
public void onFailure(Throwable caught) {
            Window.alert("Error fetching contact details");
}
 });
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
Activities & Places
• Browser History Management
• Create bookmarkable URLs
• Browser's back button and bookmarks to work as
  users expect
• MVP ?
• GWT recommends this pattern as best practice

• http://www.google.com/events/io/2011/sessions/high-
  performance-gwt-best-practices-for-writing-smaller-faster-
  apps.html
Activity
•   Represents something the user is doing
•   no Widgets or UI code
•   Restore state ("wake up")
•   Perform initialization ("set up")
•   Load a corresponding UI ("show up")
•   Call service
@Override
                                   Activity
public void start(AcceptsOneWidget containerWidget, EventBus eventBus) {
              HelloView helloView = clientFactory.getHelloView();
              helloView.setName(name);
              helloView.setPresenter(this);
              containerWidget.setWidget(helloView.asWidget());
}

/**
 * Ask user before stopping this activity
 */
@Override
public String mayStop() {
              return "Please hold on. This activity is stopping.";
}

/**
* Navigate to a new Place in the browser
 */
public void goTo(Place place) {
              clientFactory.getPlaceController().goTo(place);
}

/**
* Also some Service calls can made here
*/
Activity
public class EditContactActivity extends AbstractActivity {
              public interface IEditDisplay {
                            HasClickHandlers getSaveButton();

                         HasClickHandlers getCancelButton();

                         HasValue<String> getFirstName();
            }
            private Contact contact;
            private final ContactsServiceAsync rpcService;
            private final EventBus eventBus;
            private final IEditDisplay display;
            private final PlaceController placeController;

            public EditContactActivity(NewContactPlace place, ClientFactory clientFactory) {
                         this.rpcService = clientFactory.getContactServiceRPC();
                         this.eventBus = clientFactory.getEventBus();
                         this.contact = new Contact();
                         this.display = clientFactory.getEditContactView();
                         this.placeController = clientFactory.getPlaceController();
                         bind();
            }
Place
• Java object representing a particular state of
  the UI
• A Place can be converted to and from a URL
  history token
• PlaceController makes back
  button/bookmarks work like user expect
• PlaceTokenizers map to / from String tokens
  on URL
Place
import com.google.gwt.place.shared.Prefix;
public class EditContactPlace extends Place {
              private String placeName;
              public EditContactPlace(String token) {
                            this.placeName = token;
              }
              public String getPlaceName() {
                            return placeName;
              }
              @Prefix("edit")
              public static class Tokenizer implements PlaceTokenizer<EditContactPlace> {
                            @Override
                            public String getToken(EditContactPlace place) {
                                         return place.getPlaceName();
                            }
                            @Override
                            public EditContactPlace getPlace(String token) {
                                         return new EditContactPlace(token);
                            }
              }
PlaceHistoryMapper
import com.google.gwt.place.shared.PlaceHistoryMapper;
import com.google.gwt.place.shared.WithTokenizers;

@WithTokenizers({NewContactPlace.Tokenizer.class,
EditContactPlace.Tokenizer.class, ContactPlace.Tokenizer.class})

public interface AppPlaceHistoryMapper extends
PlaceHistoryMapper { }
AppActivityMapper
public class AppActivityMapper implements ActivityMapper {

            private ClientFactory clientFactory;

            public AppActivityMapper(ClientFactory clientFactory) {
                       super();
                       this.clientFactory = clientFactory;
            }

            @Override
            public Activity getActivity(Place place) {
                        GWT.log("Place called: " + place);

                        if(place instanceof ContactPlace) {
                                      return new ContactsActivity(clientFactory);
                        } else if (place instanceof EditContactPlace) {
                                      return new EditContactActivity((EditContactPlace) place,
clientFactory);
                        } else if (place instanceof NewContactPlace) {
                                      return new EditContactActivity((NewContactPlace) place,
clientFactory);
                        }
                        return null;
            }

}
Places : go to
Places: go to
Places: back and forth
Activities & Places
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
To Be Honest: It’s too Hard to
         Get Started on the JVM
• Modern enterprise Java is way better than 5 years ago
• But…it’s still too hard to…
  – Start a new Java project
  – Obtain and integrate all the necessary software
• Too much of our time is spent doing things that add
  too little value
• We have great building blocks, but we need
  to improve the experience
                               (Thanks to Rod Johnson :P )
Competitors ?
Essential Two Problem with JVM


              Noone owns about
                that problem




        It is still to hard to start a project on JVM
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
But result :P
Spring Roo
• Easy to use productivity tool
• Code generator – Spring based
  enterprise applications.
• Development time only.
• No negative performance impact
• No memory overhead
Spring Roo
•   Entity support
•   Field management
•   Persistence
•   JUnit testing
•   Spring MVC controller
•   Spring Security
•   GWT
•   Flex
•   ……………………
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
CloudFoundry-The Industry's Open
          Platform as a Service
• Services
  - Caldecott – tunnel into your services, explore with
    standard client tools
  - PostgreSQL, RabbitMQ

• Frameworks, Runtimes, and Tools
  - Java and Ruby Auto-Reconfiguration
  - Scala, node.JS 0.6.*, Erlang, JRuby, PHP, Python, .NET,
    Spring 3.1, Grails 2.0
  - Multi-Node Chef based deployment tools
  - Maven Plugin, Eclipse Integration
  - VMC manifests, Java Debugging, Rails Console

• Micro Cloud Foundry
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
Deploy An Application to
   CloudFoundry (1)
Deploying an Application to
          CloudFoundry (2)
• Installing vmc is easy once you have
  installed Ruby and RubyGems on your
  computer.
• prompt$ sudo gem install vmc (linux&mac)
• prompt> gem install vmc (windows)
Steps
•   prompt$ vmc target https://api.cloudfoundry.com
•   prompt$ vmc login
•   vmc passwd
•   vmc push
•   vmc apps
Hey Coding Time :P :P

• Come

More Related Content

PDF
Under the Hood: Using Spring in Grails
PDF
Under the Hood: Using Spring in Grails
PPTX
Dagger 2 - Injeção de Dependência
DOC
Converting Db Schema Into Uml Classes
PDF
React lecture
PPTX
Firebase ng2 zurich
PDF
My way to clean android - Android day salamanca edition
PDF
What's new in Android O
Under the Hood: Using Spring in Grails
Under the Hood: Using Spring in Grails
Dagger 2 - Injeção de Dependência
Converting Db Schema Into Uml Classes
React lecture
Firebase ng2 zurich
My way to clean android - Android day salamanca edition
What's new in Android O

What's hot (20)

PPTX
Typescript barcelona
PDF
Advanced Dagger talk from 360andev
PDF
Graphql, REST and Apollo
PDF
Nativescript angular
PDF
How do we use hooks
PPT
Gwt RPC
KEY
SOLID Principles
PDF
Android TDD
PPTX
An intro to cqrs
PDF
Dagger 2. Right way to do Dependency Injection
PPTX
Dagger 2. The Right Way to Dependency Injections
PDF
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
PPT
Swiss army knife Spring
PPTX
Dependency Injection for Android
PPTX
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
PDF
Bot builder v4 HOL
PDF
Android Design Patterns
TXT
New text document
PPTX
Angular mix chrisnoring
PDF
Typescript barcelona
Advanced Dagger talk from 360andev
Graphql, REST and Apollo
Nativescript angular
How do we use hooks
Gwt RPC
SOLID Principles
Android TDD
An intro to cqrs
Dagger 2. Right way to do Dependency Injection
Dagger 2. The Right Way to Dependency Injections
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Swiss army knife Spring
Dependency Injection for Android
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
Bot builder v4 HOL
Android Design Patterns
New text document
Angular mix chrisnoring
Ad

Viewers also liked (6)

PPTX
Slide Presentation of MVP Pattern Concept
PPTX
Model View Presenter (MVP) In Aspnet
PDF
Libra slide deck 2016
PPTX
Design Pattern - MVC, MVP and MVVM
PDF
Is Activity God? ~ The MVP Architecture ~
PPT
Pourquoi les PowerPoint sont lamentables
Slide Presentation of MVP Pattern Concept
Model View Presenter (MVP) In Aspnet
Libra slide deck 2016
Design Pattern - MVC, MVP and MVVM
Is Activity God? ~ The MVP Architecture ~
Pourquoi les PowerPoint sont lamentables
Ad

Similar to A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo (20)

PDF
Vaadin today and tomorrow
PDF
Vaadin 7 Today and Tomorrow
PDF
PDF
Vaadin 7
PDF
KEY
Gwt and Xtend
PDF
Clean coding-practices
KEY
Scala on Your Phone
PPTX
Android dev toolbox
PPTX
Net conf BG xamarin lecture
PDF
Android architecture blueprints overview
PDF
Durable functions 2.0 (2019-10-10)
PPTX
Reactive programming every day
PDF
PDF
Architecting your GWT applications with GWT-Platform - Lesson 02
PDF
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
KEY
Android workshop
PDF
C# Starter L06-Delegates, Event Handling and Extension Methods
PPT
Diving in the Flex Data Binding Waters
PPTX
SharePoint Conference 2018 - APIs, APIs everywhere!
Vaadin today and tomorrow
Vaadin 7 Today and Tomorrow
Vaadin 7
Gwt and Xtend
Clean coding-practices
Scala on Your Phone
Android dev toolbox
Net conf BG xamarin lecture
Android architecture blueprints overview
Durable functions 2.0 (2019-10-10)
Reactive programming every day
Architecting your GWT applications with GWT-Platform - Lesson 02
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
Android workshop
C# Starter L06-Delegates, Event Handling and Extension Methods
Diving in the Flex Data Binding Waters
SharePoint Conference 2018 - APIs, APIs everywhere!

A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo

  • 2. MVP GWT application with Spring Roo and CloudFoundry Ali Parmaksız @parmaksiza ali.parmaksiz@eu.sony.com Jan 19, 2013 http://aliparmaksiz.blogspot.com/
  • 6. Agenda • MVP Pattern (GWT) • Activites & Places (GWT) • MongoDb (NoSql) • Spring Roo (RAD for Java) • CloudFoundry (PAAS)
  • 8. ProxyServiceAsync proxyservice = ProxyService.Util.getInstance(); @UiField LabelElement listLabel; @UiField Anchor continueButton; @UiField Anchor backButton; @UiField SpanElement continueButtonSpan; @UiField SpanElement backButtonSpan; @UiField TextBox listName; @UiField Image listNameGif; @UiField HTMLPanel createListPanel; @UiField Validation validationMessages; private void callServerSideValidation(final String listNameText) { new RPCCall<ServiceResponse<ResultWithError>>() { @Override protected void callService(AsyncCallback<ServiceResponse<ResultWithError>> cb) { proxyservice.createListNameIfValid(listNameText,cb); } @Override public void onFailure(Throwable caught) { System.out.println(caught); } @Override public void onSuccess(ServiceResponse<ResultWithError> result) { List<ValidationError> validationErrors = result.getResult().getErrorList(); pressErrorMessage(validationErrors); if(validationErrors == null || validationErrors.size() == 0){ infoModel.setResult(result.getResult().getServiceResult()); infoModel.setListName(listNameText); PageNavigationReadyEvent event = new PageNavigationReadyEvent(PageNavigationReadyEvent.BUTTON_DIRECTION_FORWARD, CreateListResult.class.getName()); serviceHandlerManager.fireEvent(event); } } }.retry(0); }
  • 10. MVP Pattern(View) • View public class ContactsView extends Composite implements ContactsPresenter.Display { private final Button addButton; private final Button deleteButton; private FlexTable contactsTable; private final FlexTable contentTable; public ContactsView() { DecoratorPanel contentTableDecorator = new DecoratorPanel(); initWidget(contentTableDecorator); contentTableDecorator.setWidth("100%"); contentTableDecorator.setWidth("18em"); ************************ public void setData(List<String> data) { contactsTable.removeAllRows(); for (int i = 0; i < data.size(); ++i) { contactsTable.setWidget(i, 0, new CheckBox()); contactsTable.setText(i, 1, data.get(i)); } }
  • 11. MVP Pattern(Presenter) public class ContactsPresenter implements Presenter { private List<ContactDetails> contactDetails; public interface Display { HasClickHandlers getAddButton(); HasClickHandlers getDeleteButton(); HasClickHandlers getList(); void setData(List<String> data); int getClickedRow(ClickEvent event); List<Integer> getSelectedRows(); Widget asWidget(); } private final ContactsServiceAsync rpcService; private final HandlerManager eventBus; private final Display display;
  • 12. MVP Pattern(Presenter) private void fetchContactDetails() { rpcService.getContactDetails(new AsyncCallback<ArrayList<ContactDetails>>() { public void onSuccess(ArrayList<ContactDetails> result) { contactDetails = result; sortContactDetails(); List<String> data = new ArrayList<String>(); for (int i = 0; i < result.size(); ++i) { data.add(contactDetails.get(i).getDisplayName()); } display.setData(data); } public void onFailure(Throwable caught) { Window.alert("Error fetching contact details"); } });
  • 14. Activities & Places • Browser History Management • Create bookmarkable URLs • Browser's back button and bookmarks to work as users expect • MVP ? • GWT recommends this pattern as best practice • http://www.google.com/events/io/2011/sessions/high- performance-gwt-best-practices-for-writing-smaller-faster- apps.html
  • 15. Activity • Represents something the user is doing • no Widgets or UI code • Restore state ("wake up") • Perform initialization ("set up") • Load a corresponding UI ("show up") • Call service
  • 16. @Override Activity public void start(AcceptsOneWidget containerWidget, EventBus eventBus) { HelloView helloView = clientFactory.getHelloView(); helloView.setName(name); helloView.setPresenter(this); containerWidget.setWidget(helloView.asWidget()); } /** * Ask user before stopping this activity */ @Override public String mayStop() { return "Please hold on. This activity is stopping."; } /** * Navigate to a new Place in the browser */ public void goTo(Place place) { clientFactory.getPlaceController().goTo(place); } /** * Also some Service calls can made here */
  • 17. Activity public class EditContactActivity extends AbstractActivity { public interface IEditDisplay { HasClickHandlers getSaveButton(); HasClickHandlers getCancelButton(); HasValue<String> getFirstName(); } private Contact contact; private final ContactsServiceAsync rpcService; private final EventBus eventBus; private final IEditDisplay display; private final PlaceController placeController; public EditContactActivity(NewContactPlace place, ClientFactory clientFactory) { this.rpcService = clientFactory.getContactServiceRPC(); this.eventBus = clientFactory.getEventBus(); this.contact = new Contact(); this.display = clientFactory.getEditContactView(); this.placeController = clientFactory.getPlaceController(); bind(); }
  • 18. Place • Java object representing a particular state of the UI • A Place can be converted to and from a URL history token • PlaceController makes back button/bookmarks work like user expect • PlaceTokenizers map to / from String tokens on URL
  • 19. Place import com.google.gwt.place.shared.Prefix; public class EditContactPlace extends Place { private String placeName; public EditContactPlace(String token) { this.placeName = token; } public String getPlaceName() { return placeName; } @Prefix("edit") public static class Tokenizer implements PlaceTokenizer<EditContactPlace> { @Override public String getToken(EditContactPlace place) { return place.getPlaceName(); } @Override public EditContactPlace getPlace(String token) { return new EditContactPlace(token); } }
  • 21. AppActivityMapper public class AppActivityMapper implements ActivityMapper { private ClientFactory clientFactory; public AppActivityMapper(ClientFactory clientFactory) { super(); this.clientFactory = clientFactory; } @Override public Activity getActivity(Place place) { GWT.log("Place called: " + place); if(place instanceof ContactPlace) { return new ContactsActivity(clientFactory); } else if (place instanceof EditContactPlace) { return new EditContactActivity((EditContactPlace) place, clientFactory); } else if (place instanceof NewContactPlace) { return new EditContactActivity((NewContactPlace) place, clientFactory); } return null; } }
  • 27. To Be Honest: It’s too Hard to Get Started on the JVM • Modern enterprise Java is way better than 5 years ago • But…it’s still too hard to… – Start a new Java project – Obtain and integrate all the necessary software • Too much of our time is spent doing things that add too little value • We have great building blocks, but we need to improve the experience (Thanks to Rod Johnson :P )
  • 29. Essential Two Problem with JVM Noone owns about that problem It is still to hard to start a project on JVM
  • 32. Spring Roo • Easy to use productivity tool • Code generator – Spring based enterprise applications. • Development time only. • No negative performance impact • No memory overhead
  • 33. Spring Roo • Entity support • Field management • Persistence • JUnit testing • Spring MVC controller • Spring Security • GWT • Flex • ……………………
  • 36. CloudFoundry-The Industry's Open Platform as a Service • Services - Caldecott – tunnel into your services, explore with standard client tools - PostgreSQL, RabbitMQ • Frameworks, Runtimes, and Tools - Java and Ruby Auto-Reconfiguration - Scala, node.JS 0.6.*, Erlang, JRuby, PHP, Python, .NET, Spring 3.1, Grails 2.0 - Multi-Node Chef based deployment tools - Maven Plugin, Eclipse Integration - VMC manifests, Java Debugging, Rails Console • Micro Cloud Foundry
  • 43. Deploy An Application to CloudFoundry (1)
  • 44. Deploying an Application to CloudFoundry (2) • Installing vmc is easy once you have installed Ruby and RubyGems on your computer. • prompt$ sudo gem install vmc (linux&mac) • prompt> gem install vmc (windows)
  • 45. Steps • prompt$ vmc target https://api.cloudfoundry.com • prompt$ vmc login • vmc passwd • vmc push • vmc apps
  • 46. Hey Coding Time :P :P • Come