blob: 430426c82fc18aa205c2e30bc7329502ee07040b [file] [log] [blame]
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.sample.expenses.gwt.client;
import com.google.gwt.app.place.Activity;
import com.google.gwt.app.place.ActivityManager;
import com.google.gwt.app.place.ActivityMapper;
import com.google.gwt.app.place.CachingActivityMapper;
import com.google.gwt.app.place.FilteredActivityMapper;
import com.google.gwt.app.place.IsWidget;
import com.google.gwt.app.place.PlaceController;
import com.google.gwt.app.place.PlaceHistoryHandler;
import com.google.gwt.app.place.ProxyListPlace;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.requestfactory.client.AuthenticationFailureHandler;
import com.google.gwt.requestfactory.client.LoginWidget;
import com.google.gwt.requestfactory.shared.Receiver;
import com.google.gwt.requestfactory.shared.RequestEvent;
import com.google.gwt.requestfactory.shared.UserInformationRecord;
import com.google.gwt.requestfactory.shared.RequestEvent.State;
import com.google.gwt.sample.expenses.gwt.request.ExpensesEntityTypesProcessor;
import com.google.gwt.sample.expenses.gwt.request.ExpensesRequestFactory;
import com.google.gwt.user.client.Window.Location;
import com.google.gwt.user.client.ui.HasConstrainedValue;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.valuestore.shared.Record;
import com.google.gwt.valuestore.shared.SyncResult;
import java.util.HashSet;
import java.util.Set;
/**
* Application for browsing the entities of the Expenses app.
*/
public class Scaffold implements EntryPoint {
public void onModuleLoad() {
ScaffoldFactory factory = GWT.create(ScaffoldFactory.class);
/* App controllers and services */
final EventBus eventBus = factory.getEventBus();
final ExpensesRequestFactory requestFactory = factory.getRequestFactory();
final PlaceController placeController = factory.getPlaceController();
/* Top level UI */
final ScaffoldShell shell = factory.getShell();
/* Display loading notifications when we touch the network. */
eventBus.addHandler(RequestEvent.TYPE, new RequestEvent.Handler() {
// Only show loading status if a request isn't serviced in 250ms.
private static final int LOADING_TIMEOUT = 250;
public void onRequestEvent(RequestEvent requestEvent) {
if (requestEvent.getState() == State.SENT) {
shell.getMole().showDelayed(LOADING_TIMEOUT);
} else {
shell.getMole().hide();
}
}
});
/* Check for Authentication failures or mismatches */
eventBus.addHandler(RequestEvent.TYPE, new AuthenticationFailureHandler());
/* Add a login widget to the page */
final LoginWidget login = shell.getLoginWidget();
Receiver<UserInformationRecord> receiver = new Receiver<UserInformationRecord>() {
public void onSuccess(UserInformationRecord userInformationRecord,
Set<SyncResult> syncResults) {
login.setUserInformation(userInformationRecord);
}
};
requestFactory.userInformationRequest().getCurrentUserInformation(
Location.getHref()).fire(receiver);
/* Left side lets us pick from all the types of entities */
HasConstrainedValue<ProxyListPlace> listPlacePickerView = shell.getPlacesBox();
listPlacePickerView.setAcceptableValues(getTopPlaces());
factory.getListPlacePicker().register(eventBus, listPlacePickerView);
/*
* Top of the screen is the master list of a master / detail UI. Set it up
* to filter ProxyPlace instances to an appropriate ProxyListPlace, and put
* a cache on it to keep the same activity instance running rather than
* building a new one on each detail change.
*/
CachingActivityMapper cached = new CachingActivityMapper(
new ExpensesMasterActivities(requestFactory, placeController));
ActivityMapper masterActivityMap = new FilteredActivityMapper(
factory.getProxyPlaceToListPlace(), cached);
final ActivityManager masterActivityManager = new ActivityManager(
masterActivityMap, eventBus);
masterActivityManager.setDisplay(new Activity.Display() {
public void showActivityWidget(IsWidget widget) {
shell.getMasterPanel().setWidget(
widget == null ? null : widget.asWidget());
}
});
/* Bottom of the screen shows the details of a master / detail UI */
final ActivityManager detailsActivityManager = new ActivityManager(
new ExpensesDetailsActivities(requestFactory, placeController),
eventBus);
detailsActivityManager.setDisplay(new Activity.Display() {
public void showActivityWidget(IsWidget widget) {
shell.getDetailsPanel().setWidget(
widget == null ? null : widget.asWidget());
}
});
/* Hide the loading message */
Element loading = Document.get().getElementById("loading");
loading.getParentElement().removeChild(loading);
/* Browser history integration */
PlaceHistoryHandler placeHistoryHandler = factory.getPlaceHistoryHandler();
placeHistoryHandler.register(placeController, eventBus,
/* defaultPlace */ getTopPlaces().iterator().next());
placeHistoryHandler.handleCurrentHistory();
/* And show the user the shell */
RootLayoutPanel.get().add(shell);
}
// TODO(rjrjr) No reason to make the place objects in advance, just make
// it list the class objects themselves. Needs to be sorted by rendered name,
// too
private Set<ProxyListPlace> getTopPlaces() {
Set<Class<? extends Record>> types = ExpensesEntityTypesProcessor.getAll();
Set<ProxyListPlace> rtn = new HashSet<ProxyListPlace>(types.size());
for (Class<? extends Record> type : types) {
rtn.add(new ProxyListPlace(type));
}
return rtn;
}
}