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


Published on

GWT, MVP, Activites&Places, Spring Roo, CloudFoundry

1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

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

  1. 1. GDG 2013
  2. 2. MVP GWT application with Spring Roo and CloudFoundry Ali Parmaksız @parmaksiza ali.parmaksiz@eu.sony.com Jan 19, 2013http://aliparmaksiz.blogspot.com/
  3. 3. Agenda• MVP Pattern (GWT)• Activites & Places (GWT)• MongoDb (NoSql)• Spring Roo (RAD for Java)• CloudFoundry (PAAS)
  4. 4. MVP Pattern GWT
  5. 5. 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>>() {@Overrideprotected void callService(AsyncCallback<ServiceResponse<ResultWithError>> cb) { proxyservice.createListNameIfValid(listNameText,cb); }@Overridepublic void onFailure(Throwable caught) { System.out.println(caught);}@Overridepublic 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 = newPageNavigationReadyEvent(PageNavigationReadyEvent.BUTTON_DIRECTION_FORWARD,CreateListResult.class.getName()); serviceHandlerManager.fireEvent(event); } } }.retry(0); }
  6. 6. GWT hears you
  7. 7. 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)); } }
  8. 8. 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;
  9. 9. 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");} });
  10. 10. Activities & Places• Browser History Management• Create bookmarkable URLs• Browsers 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
  11. 11. 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
  12. 12. @Override Activitypublic 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 */@Overridepublic 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*/
  13. 13. Activitypublic 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(); }
  14. 14. 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
  15. 15. Placeimport 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); } }
  16. 16. PlaceHistoryMapperimport 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 extendsPlaceHistoryMapper { }
  17. 17. AppActivityMapperpublic 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; }}
  18. 18. Places : go to
  19. 19. Places: go to
  20. 20. Places: back and forth
  21. 21. Activities & Places
  22. 22. 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 )
  23. 23. Competitors ?
  24. 24. Essential Two Problem with JVM Noone owns about that problem It is still to hard to start a project on JVM
  25. 25. But result :P
  26. 26. Spring Roo• Easy to use productivity tool• Code generator – Spring based enterprise applications.• Development time only.• No negative performance impact• No memory overhead
  27. 27. Spring Roo• Entity support• Field management• Persistence• JUnit testing• Spring MVC controller• Spring Security• GWT• Flex• ……………………
  28. 28. CloudFoundry-The Industrys 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
  29. 29. Deploy An Application to CloudFoundry (1)
  30. 30. 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)
  31. 31. Steps• prompt$ vmc target https://api.cloudfoundry.com• prompt$ vmc login• vmc passwd• vmc push• vmc apps
  32. 32. Hey Coding Time :P :P• Come