a gwt application with mvp pattern deploying to cloudfoundry using spring roo

Post on 31-May-2015

1.347 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

TRANSCRIPT

GDG 2013

MVP GWT application with Spring Roo and CloudFoundry

Ali ParmaksızJan 19, 2013

http://aliparmaksiz.blogspot.com/

@parmaksiza

ali.parmaksiz@eu.sony.com

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>>() { @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 = 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"); } });

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

Activity@Overridepublic 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 */

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();

}

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

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> {

@Overridepublic String getToken(EditContactPlace place) {

return place.getPlaceName();}@Overridepublic 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 { }

AppActivityMapperpublic class AppActivityMapper implements ActivityMapper {

private ClientFactory clientFactory;

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

}

@Overridepublic 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

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

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• ……………………

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

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

top related